[Pkg-javascript-commits] [jquery] 01/04: New upstream version 3.1.1
Antonio Terceiro
terceiro at moszumanska.debian.org
Sat Oct 22 12:09:22 UTC 2016
This is an automated email from the git hooks/post-receive script.
terceiro pushed a commit to branch master
in repository jquery.
commit 8d9066a5169036ed98d3927425c428a4c261ae83
Author: Antonio Terceiro <terceiro at debian.org>
Date: Sun Oct 16 13:50:36 2016 -0200
New upstream version 3.1.1
---
.babelrc | 3 +
.editorconfig | 19 +-
.jshintignore => .eslintignore | 4 +-
.eslintrc.json | 7 +
.github/ISSUE_TEMPLATE.md | 24 +
.github/PULL_REQUEST_TEMPLATE.md | 16 +
.gitignore | 7 +-
.jscsrc | 10 -
.jshintrc | 14 -
.mailmap | 6 +-
.npmignore | 4 +-
.npmrc | 1 +
.travis.yml | 2 +-
AUTHORS.txt | 17 +-
Gruntfile.js | 131 ++---
README.md | 41 +-
build/release.js | 21 +-
build/release/cdn.js | 9 +-
build/release/dist.js | 33 +-
build/tasks/build.js | 83 ++-
build/tasks/install_old_jsdom.js | 20 -
build/tasks/lib/spawn_test.js | 6 +-
build/tasks/promises_aplus_tests.js | 14 +-
external/sizzle/dist/sizzle.js | 121 +++--
external/sizzle/dist/sizzle.min.js | 4 +-
external/sizzle/dist/sizzle.min.map | 2 +-
package.json | 64 ++-
src/.eslintrc.json | 18 +
src/.jshintrc | 29 --
src/ajax.js | 30 +-
src/ajax/jsonp.js | 2 +
src/ajax/load.js | 9 +-
src/ajax/parseJSON.js | 9 -
src/ajax/parseXML.js | 5 +-
src/ajax/script.js | 2 +
src/ajax/var/location.js | 2 +
src/ajax/var/nonce.js | 2 +
src/ajax/var/rquery.js | 2 +
src/ajax/xhr.js | 10 +-
src/attributes.js | 2 +
src/attributes/attr.js | 37 +-
src/attributes/classes.js | 29 +-
src/attributes/prop.js | 46 +-
src/attributes/support.js | 8 +-
src/attributes/val.js | 51 +-
src/callbacks.js | 8 +-
src/core.js | 78 +--
src/core/DOMEval.js | 2 +
src/core/access.js | 17 +-
src/core/init.js | 2 +
src/core/parseHTML.js | 30 +-
src/core/ready-no-deferred.js | 105 ++++
src/core/ready.js | 61 ++-
src/core/readyException.js | 13 +
src/core/stripAndCollapse.js | 14 +
src/core/support.js | 4 +-
src/core/var/rsingleTag.js | 1 +
src/css.js | 33 +-
src/css/addGetHookIf.js | 2 +
src/css/adjustCSS.js | 10 +-
src/css/curCSS.js | 8 +-
src/css/hiddenVisibleSelectors.js | 8 +-
src/css/showHide.js | 17 +-
src/css/support.js | 73 ++-
src/css/var/cssExpand.js | 2 +
src/css/var/getStyles.js | 6 +-
src/css/var/isHidden.js | 16 -
src/css/var/isHiddenWithinTree.js | 34 ++
src/css/var/rmargin.js | 2 +
src/css/var/rnumnonpx.js | 2 +
src/css/var/swap.js | 2 +
src/data.js | 38 +-
src/data/Data.js | 12 +-
src/data/var/acceptData.js | 3 +-
src/data/var/dataPriv.js | 2 +
src/data/var/dataUser.js | 2 +
src/deferred.js | 116 +++--
src/deferred/exceptionHook.js | 6 +-
src/deprecated.js | 4 +
src/dimensions.js | 2 +
src/effects.js | 47 +-
src/effects/Tween.js | 21 +-
src/effects/animatedSelector.js | 4 +-
src/event.js | 268 +++++-----
src/event/ajax.js | 2 +
src/event/alias.js | 2 +
src/event/focusin.js | 8 +-
src/event/support.js | 2 +
src/event/trigger.js | 20 +-
src/exports/amd.js | 2 +
src/exports/global.js | 8 +
src/jquery.js | 7 +-
src/manipulation.js | 18 +-
src/manipulation/_evalUrl.js | 2 +
src/manipulation/buildFragment.js | 6 +-
src/manipulation/getAll.js | 30 +-
src/manipulation/setGlobalEval.js | 2 +
src/manipulation/support.js | 8 +-
src/manipulation/var/rcheckableType.js | 2 +
src/manipulation/var/rscriptType.js | 2 +
src/manipulation/var/rtagName.js | 2 +
src/manipulation/wrapMap.js | 6 +-
src/offset.js | 17 +-
src/outro.js | 2 -
src/queue.js | 2 +
src/queue/delay.js | 2 +
src/selector-native.js | 32 +-
src/selector-sizzle.js | 7 +-
src/selector.js | 4 +-
src/serialize.js | 37 +-
src/traversing.js | 2 +
src/traversing/findFilter.js | 41 +-
src/traversing/var/dir.js | 2 +
src/traversing/var/rneedsContext.js | 2 +
src/traversing/var/siblings.js | 2 +
src/var/ObjectFunctionString.js | 7 +
src/var/arr.js | 2 +
src/var/class2type.js | 1 +
src/var/concat.js | 2 +
src/var/document.js | 2 +
src/var/documentElement.js | 2 +
src/var/fnToString.js | 7 +
src/var/getProto.js | 5 +
src/var/hasOwn.js | 2 +
src/var/indexOf.js | 2 +
src/var/pnum.js | 2 +
src/var/push.js | 2 +
src/var/rcssNum.js | 2 +
src/var/rnothtmlwhite.js | 8 +
src/var/rnotwhite.js | 3 -
src/var/slice.js | 2 +
src/var/support.js | 1 +
src/var/toString.js | 2 +
src/wrap.js | 2 +
src/{intro.js => wrapper.js} | 23 +-
test/{.jshintrc => .eslintrc.json} | 44 +-
test/data/ajax/onunload.html | 3 +-
test/data/ajax/unreleasedXHR.html | 3 +-
test/data/core/aliased.html | 7 +-
test/data/core/cc_on.html | 3 +-
test/data/core/dynamic_ready.html | 5 +-
test/data/core/onready.html | 3 +-
test/data/css/cssWidthBeforeDocReady.html | 4 +-
test/data/data/dataAttrs.html | 3 +-
test/data/dimensions/documentLarge.html | 4 +
test/data/event/focusElem.html | 3 +-
test/data/event/focusinCrossFrame.html | 3 +-
test/data/event/interactiveReady.html | 7 +-
test/data/event/promiseReady.html | 3 +-
test/data/event/syncReady.html | 3 +-
test/data/event/triggerunload.html | 3 +-
test/data/iframeTest.js | 8 +
test/data/manipulation/iframe-denied.html | 3 +-
test/data/manipulation/scripts-context.html | 7 +-
test/data/offset/absolute.html | 2 +
test/data/offset/body.html | 2 +
test/data/offset/fixed.html | 2 +
test/data/offset/relative.html | 2 +
test/data/offset/scroll.html | 2 +
test/data/offset/static.html | 2 +
test/data/offset/table.html | 2 +
test/data/selector/html5_selector.html | 4 +-
test/data/selector/sizzle_cache.html | 4 +
test/data/support/bodyBackground.html | 3 +-
test/data/support/csp.js | 2 +-
test/data/support/csp.php | 1 +
test/data/test3.html | 1 +
test/data/testinit.js | 144 +++---
test/data/testsuite.css | 16 +-
test/index.html | 2 +-
test/jquery.js | 5 +-
test/node_smoke_tests/.eslintrc.json | 7 +
test/node_smoke_tests/.jshintrc | 14 -
.../iterable_with_symbol_polyfill.js | 2 -
.../node_smoke_tests/lib/ensure_iterability_es6.js | 2 -
test/promises_aplus_adapters/.eslintrc.json | 4 +
.../deferred.js} | 6 +-
test/promises_aplus_adapters/when.js | 49 ++
test/unit/ajax.js | 152 ++++--
test/unit/attributes.js | 208 +++++++-
test/unit/basic.js | 29 +-
test/unit/core.js | 292 ++++++-----
test/unit/css.js | 134 +++--
test/unit/data.js | 16 +-
test/unit/deferred.js | 557 ++++++++++++++-------
test/unit/deprecated.js | 76 ++-
test/unit/dimensions.js | 82 ++-
test/unit/effects.js | 136 ++---
test/unit/event.js | 282 +++++++----
test/unit/manipulation.js | 74 ++-
test/unit/offset.js | 156 +++---
test/unit/queue.js | 2 +-
test/unit/ready.js | 108 +++-
test/unit/selector.js | 44 +-
test/unit/serialize.js | 68 +--
test/unit/support.js | 42 +-
test/unit/traversing.js | 47 +-
test/unit/tween.js | 8 +-
test/unit/wrap.js | 4 +-
199 files changed, 3472 insertions(+), 1855 deletions(-)
diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..c13c5f6
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015"]
+}
diff --git a/.editorconfig b/.editorconfig
index 06dbe06..b5bd7f6 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -3,25 +3,14 @@
root = true
-
[*]
+indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
-# Tabs in JS unless otherwise specified
-[**.js]
-indent_style = tab
-
-[test/**.xml]
-indent_style = tab
-
-[test/**.php]
-indent_style = tab
+[package.json]
+indent_style = space
+indent_size = 2
-[test/**.html]
-indent_style = tab
-
-[test/**.css]
-indent_style = tab
diff --git a/.jshintignore b/.eslintignore
similarity index 91%
rename from .jshintignore
rename to .eslintignore
index 1ddafd6..484ceee 100644
--- a/.jshintignore
+++ b/.eslintignore
@@ -1,6 +1,6 @@
external
-src/intro.js
-src/outro.js
+node_modules
+*.min.js
test/data/jquery-1.9.1.js
test/data/badcall.js
test/data/badjson.js
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..6dcb635
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,7 @@
+{
+ "extends": "eslint-config-jquery",
+ "root": true,
+ "env": {
+ "node": true
+ }
+}
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..a3c7d5b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,24 @@
+<!--
+Feature Requests:
+ Please read https://github.com/jquery/jquery/wiki/Adding-new-features
+ Most features should start as plugins outside of jQuery.
+
+Bug Reports:
+ Note that we only can fix bugs in the latest (1.x, 2.x, 3.x) versions of jQuery.
+ Briefly describe the issue you've encountered
+ * What do you expect to happen?
+ * What acually happens?
+ * Which browsers are affected?
+ Provide a *minimal* test case, see https://webkit.org/test-case-reduction/
+ Use the latest shipping version of jQuery in your test case!
+ We prefer test cases on https://jsbin.com or https://jsfiddle.net
+
+Frequently Reported Issues:
+ * Selectors with '#' break: See https://github.com/jquery/jquery/issues/2824
+-->
+
+### Description ###
+
+
+### Link to test case ###
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..0ec4516
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,16 @@
+### Summary ###
+<!--
+Describe what this PR does. All but trivial changes (e.g. typos)
+should start with an issue. Mention the issue number here.
+-->
+
+
+### Checklist ###
+Mark an `[x]` for completed items, if you're not sure leave them unchecked and we can assist.
+
+* [ ] All authors have signed the CLA at https://contribute.jquery.com/CLA/
+* [ ] New tests have been added to show the fix or feature works
+* [ ] Grunt build and unit tests pass locally with these changes
+* [ ] If needed, a docs issue/PR was created at https://github.com/jquery/api.jquery.com
+
+Thanks! Bots and humans will be around shortly to check it out.
diff --git a/.gitignore b/.gitignore
index eae5df6..8cb522d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,12 @@
.bower.json
.sizecache.json
-/dist
+npm-debug.log*
+
+# Ignore everything in dist folder except for eslint config
+/dist/*
+!/dist/.eslintrc.json
+
/node_modules
/test/node_smoke_tests/lib/ensure_iterability.js
diff --git a/.jscsrc b/.jscsrc
deleted file mode 100644
index c460130..0000000
--- a/.jscsrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "preset": "jquery",
-
- // remove after https://github.com/jscs-dev/node-jscs/issues/1685
- // and https://github.com/jscs-dev/node-jscs/issues/1686
- "requireCapitalizedComments": null,
-
- "excludeFiles": [ "external", "src/intro.js", "src/outro.js",
- "test/node_smoke_tests/lib/ensure_iterability.js", "node_modules" ]
-}
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index 1445c7b..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "boss": true,
- "curly": true,
- "eqeqeq": true,
- "eqnull": true,
- "expr": true,
- "immed": true,
- "noarg": true,
- "quotmark": "double",
- "undef": true,
- "unused": true,
-
- "node": true
-}
diff --git a/.mailmap b/.mailmap
index 2949a51..66bd7e7 100644
--- a/.mailmap
+++ b/.mailmap
@@ -86,8 +86,10 @@ Scott Jehl <scottjehl at gmail.com> <scott at scottjehl.com>
Sebastian Burkhard <sebi.burkhard at gmail.com>
Senya Pugach <upisfree at outlook.com>
Thomas Tortorini <thomastortorini at gmail.com> Mr21
-Timmy Willison <timmywillisn at gmail.com>
-Timmy Willison <timmywillisn at gmail.com> <tim.willison at thisismedium.com>
+Timmy Willison <4timmywil at gmail.com>
+Timmy Willison <4timmywil at gmail.com> <timmywillisn at gmail.com>
+Timmy Willison <4timmywil at gmail.com> <tim.willison at thisismedium.com>
+Timmy Willison <4timmywil at gmail.com> <timmywil at users.noreply.github.com>
Timo Tijhof <krinklemail at gmail.com>
TJ Holowaychuk <tj at vision-media.ca>
Tom H Fuertes <tomfuertes at gmail.com>
diff --git a/.npmignore b/.npmignore
index d510949..5af00bb 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,5 +1,5 @@
-.jshintignore
-.jshintrc
+.eslintignore
+.eslintrc.json
/.editorconfig
/.gitattributes
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..cffe8cd
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+save-exact=true
diff --git a/.travis.yml b/.travis.yml
index 5e3f4a3..7992702 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,4 +4,4 @@ node_js:
- "0.10"
- "0.12"
- "4"
-- "5"
+- "6"
diff --git a/AUTHORS.txt b/AUTHORS.txt
index 685e2e6..334363d 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -77,7 +77,7 @@ Jared Grippe <jared at deadlyicon.com>
Sylvester Keil <sylvester at keil.or.at>
Brandon Sterne <bsterne at mozilla.com>
Mathias Bynens <mathias at qiwi.be>
-Timmy Willison <timmywillisn at gmail.com>
+Timmy Willison <4timmywil at gmail.com>
Corey Frang <gnarf37 at gmail.com>
Digitalxero <digitalxero>
Anton Kovalyov <anton at kovalyov.net>
@@ -278,3 +278,18 @@ Josh Soref <apache at soref.com>
Henry Wong <henryw4k at gmail.com>
Jon Dufresne <jon.dufresne at gmail.com>
Martijn W. van der Lee <martijn at vanderlee.com>
+Devin Wilson <dwilson6.github at gmail.com>
+Steve Mao <maochenyan at gmail.com>
+Zack Hall <zackhall at outlook.com>
+Bernhard M. Wiedemann <jquerybmw at lsmod.de>
+Todor Prikumov <tono_pr at abv.bg>
+Jha Naman <createnaman at gmail.com>
+William Robinet <william.robinet at conostix.com>
+Alexander Lisianoi <all3fox at gmail.com>
+Vitaliy Terziev <vitaliyterziev at gmail.com>
+Joe Trumbull <trumbull.j at gmail.com>
+Alexander K <xpyro at ya.ru>
+Damian Senn <jquery at topaxi.codes>
+Ralin Chimev <ralin.chimev at gmail.com>
+Felipe Sateler <fsateler at gmail.com>
+Christophe Tafani-Dereeper <christophetd at hotmail.fr>
diff --git a/Gruntfile.js b/Gruntfile.js
index 1e204ad..7090a1a 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -2,7 +2,8 @@ module.exports = function( grunt ) {
"use strict";
function readOptionalJSON( filepath ) {
- var data = {};
+ var stripJSONComments = require( "strip-json-comments" ),
+ data = {};
try {
data = JSON.parse( stripJSONComments(
fs.readFileSync( filepath, { encoding: "utf8" } )
@@ -12,24 +13,15 @@ module.exports = function( grunt ) {
}
var fs = require( "fs" ),
- stripJSONComments = require( "strip-json-comments" ),
gzip = require( "gzip-js" ),
- srcHintOptions = readOptionalJSON( "src/.jshintrc" ),
- newNode = !/^v0/.test( process.version ),
-
- // Allow to skip jsdom-related tests in Node.js < 1.0.0
- runJsdomTests = newNode || ( function() {
- try {
- require( "jsdom" );
- return true;
- } catch ( e ) {
- return false;
- }
- } )();
+ oldNode = /^v0\./.test( process.version );
- // The concatenated file won't pass onevar
- // But our modules can
- delete srcHintOptions.onevar;
+ // Support: Node.js <4
+ // Skip running tasks that dropped support for Node.js 0.10 & 0.12
+ // in those Node versions.
+ function runIfNewNode( task ) {
+ return oldNode ? "print_old_node_message:" + task : task;
+ }
if ( !grunt.option( "filename" ) ) {
grunt.option( "filename", "jquery.js" );
@@ -75,6 +67,10 @@ module.exports = function( grunt ) {
callbacks: [ "deferred" ],
css: [ "effects", "dimensions", "offset" ],
"css/showHide": [ "effects" ],
+ deferred: {
+ remove: [ "ajax", "effects", "queue", "core/ready" ],
+ include: [ "core/ready-no-deferred" ]
+ },
sizzle: [ "css/hiddenVisibleSelectors", "effects/animatedSelector" ]
}
}
@@ -101,7 +97,7 @@ module.exports = function( grunt ) {
"requirejs/require.js": "requirejs/require.js",
- "sinon/fake_timers.js": "sinon/lib/sinon/util/fake_timers.js",
+ "sinon/sinon.js": "sinon/pkg/sinon.js",
"sinon/LICENSE.txt": "sinon/LICENSE"
}
}
@@ -111,34 +107,22 @@ module.exports = function( grunt ) {
src: [ "package.json" ]
}
},
- jshint: {
- all: {
- src: [
- "src/**/*.js", "Gruntfile.js", "test/**/*.js", "build/**/*.js"
- ],
- options: {
- jshintrc: true
- }
+ eslint: {
+ options: {
+
+ // See https://github.com/sindresorhus/grunt-eslint/issues/119
+ quiet: true
},
+
+ // We have to explicitly declare "src" property otherwise "newer"
+ // task wouldn't work properly :/
dist: {
- src: "dist/jquery.js",
- options: srcHintOptions
+ src: "dist/jquery.js"
+ },
+ dev: {
+ src: [ "src/**/*.js", "Gruntfile.js", "test/**/*.js", "build/**/*.js" ]
}
},
- jscs: {
- src: "src",
- gruntfile: "Gruntfile.js",
-
- // Check parts of tests that pass
- test: [
- "test/data/testrunner.js",
- "test/unit/animation.js",
- "test/unit/basic.js",
- "test/unit/tween.js",
- "test/unit/wrap.js"
- ],
- build: "build"
- },
testswarm: {
tests: [
@@ -171,7 +155,7 @@ module.exports = function( grunt ) {
]
},
watch: {
- files: [ "<%= jshint.all.src %>" ],
+ files: [ "<%= eslint.dev.src %>" ],
tasks: [ "dev" ]
},
uglify: {
@@ -203,24 +187,55 @@ module.exports = function( grunt ) {
} );
// Load grunt tasks from NPM packages
- require( "load-grunt-tasks" )( grunt );
+ // Support: Node.js <4
+ // Don't load the eslint task in old Node.js, it won't parse.
+ require( "load-grunt-tasks" )( grunt, {
+ pattern: oldNode ? [ "grunt-*", "!grunt-eslint" ] : [ "grunt-*" ]
+ } );
// Integrate jQuery specific tasks
grunt.loadTasks( "build/tasks" );
- grunt.registerTask( "lint", [ "jsonlint", "jshint", "jscs" ] );
-
- // Don't run Node-related tests in Node.js < 1.0.0 as they require an old
- // jsdom version that needs compiling, making it harder for people to compile
- // jQuery on Windows. (see gh-2519)
- grunt.registerTask( "test_fast", runJsdomTests ? [ "node_smoke_tests" ] : [] );
-
- grunt.registerTask( "test", [ "test_fast" ].concat(
- runJsdomTests ? [ "promises_aplus_tests" ] : []
- ) );
-
- // Short list as a high frequency watch task
- grunt.registerTask( "dev", [ "build:*:*", "lint", "uglify", "remove_map_comment", "dist:*" ] );
+ grunt.registerTask( "print_old_node_message", function() {
+ var task = [].slice.call( arguments ).join( ":" );
+ grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." );
+ } );
- grunt.registerTask( "default", [ "dev", "test_fast", "compare_size" ] );
+ grunt.registerTask( "lint", [
+ "jsonlint",
+ runIfNewNode( "eslint" )
+ ] );
+
+ grunt.registerTask( "lint:newer", [
+ "newer:jsonlint",
+ runIfNewNode( "newer:eslint" )
+ ] );
+
+ grunt.registerTask( "test:fast", runIfNewNode( "node_smoke_tests" ) );
+ grunt.registerTask( "test:slow", runIfNewNode( "promises_aplus_tests" ) );
+
+ grunt.registerTask( "test", [
+ "test:fast",
+ "test:slow"
+ ] );
+
+ grunt.registerTask( "dev", [
+ "build:*:*",
+ runIfNewNode( "newer:eslint:dev" ),
+ "newer:uglify",
+ "remove_map_comment",
+ "dist:*",
+ "compare_size"
+ ] );
+
+ grunt.registerTask( "default", [
+ runIfNewNode( "eslint:dev" ),
+ "build:*:*",
+ "uglify",
+ "remove_map_comment",
+ "dist:*",
+ runIfNewNode( "eslint:dist" ),
+ "test:fast",
+ "compare_size"
+ ] );
};
diff --git a/README.md b/README.md
index e96f625..9e5b130 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ What you need to build your own jQuery
In order to build jQuery, you need to have the latest Node.js/npm and git 1.7 or later. Earlier versions might work, but are not supported.
-For Windows, you have to download and install [git](http://git-scm.com/downloads) and [Node.js](https://nodejs.org/en/download/).
+For Windows, you have to download and install [git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org/en/download/).
OS X users should install [Homebrew](http://brew.sh/). Once Homebrew is installed, run `brew install git` to install git,
and `brew install node` to install Node.js.
@@ -340,32 +340,33 @@ url("data/test.php?foo=bar");
```
-### Load tests in an iframe ###
+### Run tests in an iframe ###
-Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
-and fires the given callback on jQuery ready (using the jQuery loading from that page)
-and passes the iFrame's jQuery to the callback.
+Some tests may require a document other than the standard test fixture, and
+these can be run in a separate iframe. The actual test code and assertions
+remain in jQuery's main test files; only the minimal test fixture markup
+and setup code should be placed in the iframe file.
```js
-testIframe( fileName, testName, callback );
+testIframe( testName, fileName,
+ function testCallback(
+ assert, jQuery, window, document,
+ [ additional args ] ) {
+ ...
+ } );
```
-Callback arguments:
+This loads a page, constructing a url with fileName `"./data/" + fileName`.
+The iframed page determines when the callback occurs in the test by
+including the "/test/data/iframeTest.js" script and calling
+`startIframeTest( [ additional args ] )` when appropriate. Often this
+will be after either document ready or `window.onload` fires.
-```js
-callback( jQueryFromIFrame, iFrameWindow, iFrameDocument );
-```
-
-### Load tests in an iframe (window.iframeCallback) ###
+The `testCallback` receives the QUnit `assert` object created by `testIframe`
+for this test, followed by the global `jQuery`, `window`, and `document` from
+the iframe. If the iframe code passes any arguments to `startIframeTest`,
+they follow the `document` argument.
-Loads a given page constructing a url with fileName: `"./data/" + fileName + ".html"`
-The given callback is fired when window.iframeCallback is called by the page.
-The arguments passed to the callback are the same as the
-arguments passed to window.iframeCallback, whatever that may be.
-
-```js
-testIframeWithCallback( testName, fileName, callback );
-```
Questions?
----------
diff --git a/build/release.js b/build/release.js
index a333d05..22cd90c 100644
--- a/build/release.js
+++ b/build/release.js
@@ -1,3 +1,4 @@
+var fs = require( "fs" );
module.exports = function( Release ) {
@@ -8,7 +9,8 @@ module.exports = function( Release ) {
"dist/jquery.min.map",
"dist/jquery.slim.js",
"dist/jquery.slim.min.js",
- "dist/jquery.slim.min.map"
+ "dist/jquery.slim.min.map",
+ "src/core.js"
],
cdn = require( "./release/cdn" ),
dist = require( "./release/dist" ),
@@ -19,6 +21,7 @@ module.exports = function( Release ) {
Release.define( {
npmPublish: true,
issueTracker: "github",
+
/**
* Ensure the repo is in a proper state before release
* @param {Function} callback
@@ -26,6 +29,17 @@ module.exports = function( Release ) {
checkRepoState: function( callback ) {
ensureSizzle( Release, callback );
},
+
+ /**
+ * Set the version in the src folder for distributing AMD
+ */
+ _setSrcVersion: function() {
+ var corePath = __dirname + "/../src/core.js",
+ contents = fs.readFileSync( corePath, "utf8" );
+ contents = contents.replace( /@VERSION/g, Release.newVersion );
+ fs.writeFileSync( corePath, contents, "utf8" );
+ },
+
/**
* Generates any release artifacts that should be included in the release.
* The callback must be invoked with an array of files that should be
@@ -40,8 +54,10 @@ module.exports = function( Release ) {
"Grunt custom failed"
);
cdn.makeReleaseCopies( Release );
+ Release._setSrcVersion();
callback( files );
},
+
/**
* Acts as insertion point for restoring Release.dir.repo
* It was changed to reuse npm publish code in jquery-release
@@ -53,6 +69,7 @@ module.exports = function( Release ) {
Release.dir.repo = Release.dir.origRepo || Release.dir.repo;
return npmTags();
},
+
/**
* Publish to distribution repo and npm
* @param {Function} callback
@@ -67,7 +84,7 @@ module.exports = function( Release ) {
module.exports.dependencies = [
"archiver at 0.14.2",
- "shelljs at 0.2.6",
+ "shelljs at 0.7.0",
"npm at 2.3.0",
"chalk at 1.1.1"
];
diff --git a/build/release/cdn.js b/build/release/cdn.js
index 3b48511..0506062 100644
--- a/build/release/cdn.js
+++ b/build/release/cdn.js
@@ -40,11 +40,12 @@ function makeReleaseCopies( Release ) {
// Map files need to reference the new uncompressed name;
// assume that all files reside in the same directory.
- // "file":"jquery.min.js","sources":["jquery.js"]
+ // "file":"jquery.min.js" ... "sources":["jquery.js"]
text = fs.readFileSync( builtFile, "utf8" )
- .replace( /"file":"([^"]+)","sources":\["([^"]+)"\]/,
- "\"file\":\"" + unpathedFile.replace( /\.min\.map/, ".min.js" ) +
- "\",\"sources\":[\"" + unpathedFile.replace( /\.min\.map/, ".js" ) + "\"]" );
+ .replace( /"file":"([^"]+)"/,
+ "\"file\":\"" + unpathedFile.replace( /\.min\.map/, ".min.js\"" ) )
+ .replace( /"sources":\["([^"]+)"\]/,
+ "\"sources\":[\"" + unpathedFile.replace( /\.min\.map/, ".js" ) + "\"]" );
fs.writeFileSync( releaseFile, text );
} else if ( builtFile !== releaseFile ) {
shell.cp( "-f", builtFile, releaseFile );
diff --git a/build/release/dist.js b/build/release/dist.js
index fc12a1a..e0237fe 100644
--- a/build/release/dist.js
+++ b/build/release/dist.js
@@ -55,24 +55,49 @@ module.exports = function( Release, files, complete ) {
function copy() {
// Copy dist files
- var distFolder = Release.dir.dist + "/dist";
+ var distFolder = Release.dir.dist + "/dist",
+ externalFolder = Release.dir.dist + "/external",
+ rmIgnore = files
+ .concat( [
+ "README.md",
+ "node_modules"
+ ] )
+ .map( function( file ) {
+ return Release.dir.dist + "/" + file;
+ } );
+
+ shell.config.globOptions = {
+ ignore: rmIgnore
+ };
+
+ // Remove extraneous files before copy
+ shell.rm( "-rf", Release.dir.dist + "/**/*" );
+
shell.mkdir( "-p", distFolder );
files.forEach( function( file ) {
shell.cp( "-f", Release.dir.repo + "/" + file, distFolder );
} );
+ // Copy Sizzle
+ shell.mkdir( "-p", externalFolder );
+ shell.cp( "-rf", Release.dir.repo + "/external/sizzle", externalFolder );
+
// Copy other files
extras.forEach( function( file ) {
shell.cp( "-rf", Release.dir.repo + "/" + file, Release.dir.dist );
} );
+ // Remove the wrapper from the dist repo
+ shell.rm( "-f", Release.dir.dist + "/src/wrapper.js" );
+
// Write generated bower file
fs.writeFileSync( Release.dir.dist + "/bower.json", generateBower() );
console.log( "Adding files to dist..." );
- Release.exec( "git add .", "Error adding files." );
+
+ Release.exec( "git add -A", "Error adding files." );
Release.exec(
- "git commit -m 'Release " + Release.newVersion + "'",
+ "git commit -m \"Release " + Release.newVersion + "\"",
"Error committing files."
);
console.log();
@@ -80,7 +105,7 @@ module.exports = function( Release, files, complete ) {
console.log( "Tagging release on dist..." );
Release.exec( "git tag " + Release.newVersion,
"Error tagging " + Release.newVersion + " on dist repo." );
- Release.tagTime = Release.exec( "git log -1 --format='%ad'",
+ Release.tagTime = Release.exec( "git log -1 --format=\"%ad\"",
"Error getting tag timestamp." ).trim();
}
diff --git a/build/tasks/build.js b/build/tasks/build.js
index c9f1dae..1579691 100644
--- a/build/tasks/build.js
+++ b/build/tasks/build.js
@@ -10,12 +10,21 @@ module.exports = function( grunt ) {
var fs = require( "fs" ),
requirejs = require( "requirejs" ),
+ Insight = require( "insight" ),
+ pkg = require( "../../package.json" ),
srcFolder = __dirname + "/../../src/",
rdefineEnd = /\}\s*?\);[^}\w]*$/,
+ read = function( fileName ) {
+ return grunt.file.read( srcFolder + fileName );
+ },
+ wrapper = read( "wrapper.js" ).split( /\/\/ \@CODE\n\/\/[^\n]+/ ),
config = {
baseUrl: "src",
name: "jquery",
+ // Allow strict mode
+ useStrict: true,
+
// We have multiple minify steps
optimize: "none",
@@ -28,11 +37,8 @@ module.exports = function( grunt ) {
// Avoid breaking semicolons inserted by r.js
skipSemiColonInsertion: true,
wrap: {
- startFile: "src/intro.js",
- endFile: [ "src/exports/global.js", "src/outro.js" ]
- },
- paths: {
- sizzle: "../external/sizzle/dist/sizzle"
+ start: wrapper[ 0 ].replace( /\/\*\s*eslint(?: |-).*\s*\*\/\n/, "" ),
+ end: wrapper[ 1 ]
},
rawText: {},
onBuildWrite: convert
@@ -54,11 +60,16 @@ module.exports = function( grunt ) {
// Convert var modules
if ( /.\/var\//.test( path.replace( process.cwd(), "" ) ) ) {
contents = contents
- .replace( /define\([\w\W]*?return/, "var " + ( /var\/([\w-]+)/.exec( name )[ 1 ] ) + " =" )
+ .replace(
+ /define\([\w\W]*?return/,
+ "var " +
+ ( /var\/([\w-]+)/.exec( name )[ 1 ] ) +
+ " ="
+ )
.replace( rdefineEnd, "" );
// Sizzle treatment
- } else if ( /^sizzle$/.test( name ) ) {
+ } else if ( /\/sizzle$/.test( name ) ) {
contents = "var Sizzle =\n" + contents
// Remove EXPOSE lines from Sizzle
@@ -74,7 +85,7 @@ module.exports = function( grunt ) {
// Remove define wrappers, closure ends, and empty declarations
contents = contents
- .replace( /define\([^{]*?{/, "" )
+ .replace( /define\([^{]*?{\s*(?:("|')use strict\1(?:;|))?/, "" )
.replace( rdefineEnd, "" );
// Remove anything wrapped with
@@ -120,6 +131,7 @@ module.exports = function( grunt ) {
excluded = [],
included = [],
version = grunt.config( "pkg.version" ),
+
/**
* Recursively calls the excluder to remove on all modules in the list
* @param {Array} list
@@ -157,6 +169,7 @@ module.exports = function( grunt ) {
} );
}
},
+
/**
* Adds the specified module to the excluded or included list, depending on the flag
* @param {String} flag A module path relative to
@@ -164,7 +177,8 @@ module.exports = function( grunt ) {
* whether it should included or excluded
*/
excluder = function( flag ) {
- var m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
+ var additional,
+ m = /^(\+|\-|)([\w\/-]+)$/.exec( flag ),
exclude = m[ 1 ] === "-",
module = m[ 2 ];
@@ -188,8 +202,16 @@ module.exports = function( grunt ) {
}
}
+ additional = removeWith[ module ];
+
// Check removeWith list
- excludeList( removeWith[ module ] );
+ if ( additional ) {
+ excludeList( additional.remove || additional );
+ if ( additional.include ) {
+ included = included.concat( additional.include );
+ grunt.log.writeln( "+" + additional.include );
+ }
+ }
} else {
grunt.log.error( "Module \"" + module + "\" is a minimum requirement." );
if ( module === "selector" ) {
@@ -310,10 +332,47 @@ module.exports = function( grunt ) {
// grunt build:*:*:+ajax:-dimensions:-effects:-offset
grunt.registerTask( "custom", function() {
var args = this.args,
- modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "";
+ modules = args.length ? args[ 0 ].replace( /,/g, ":" ) : "",
+ done = this.async(),
+ insight = new Insight( {
+ trackingCode: "UA-1076265-4",
+ pkg: pkg
+ } );
+
+ function exec( trackingAllowed ) {
+ var tracks = args.length ? args[ 0 ].split( "," ) : [];
+ var defaultPath = [ "build", "custom" ];
+
+ tracks = tracks.map( function( track ) {
+ return track.replace( /\//g, "+" );
+ } );
+
+ if ( trackingAllowed ) {
+
+ // Track individuals
+ tracks.forEach( function( module ) {
+ var path = defaultPath.concat( [ "individual" ], module );
+
+ insight.track.apply( insight, path );
+ } );
+
+ // Track full command
+ insight.track.apply( insight, defaultPath.concat( [ "full" ], tracks ) );
+ }
+
+ grunt.task.run( [ "build:*:*" + ( modules ? ":" + modules : "" ), "uglify", "dist" ] );
+ done();
+ }
grunt.log.writeln( "Creating custom build...\n" );
- grunt.task.run( [ "build:*:*" + ( modules ? ":" + modules : "" ), "uglify", "dist" ] );
+ // Ask for permission the first time
+ if ( insight.optOut === undefined ) {
+ insight.askPermission( null, function( error, result ) {
+ exec( result );
+ } );
+ } else {
+ exec( !insight.optOut );
+ }
} );
};
diff --git a/build/tasks/install_old_jsdom.js b/build/tasks/install_old_jsdom.js
deleted file mode 100644
index 271e0cb..0000000
--- a/build/tasks/install_old_jsdom.js
+++ /dev/null
@@ -1,20 +0,0 @@
-module.exports = function( grunt ) {
-
- "use strict";
-
- // Run this task to run jsdom-related tests on Node.js < 1.0.0.
- grunt.registerTask( "old_jsdom", function() {
- if ( !/^v0/.test( process.version ) ) {
- console.warn( "The old_jsdom task doesn\'t need to be run in io.js or new Node.js" );
- return;
- }
-
- // Use npm on the command-line
- // There is no local npm
- grunt.util.spawn( {
- cmd: "npm",
- args: [ "install", "jsdom at 3" ],
- opts: { stdio: "inherit" }
- }, this.async() );
- } );
-};
diff --git a/build/tasks/lib/spawn_test.js b/build/tasks/lib/spawn_test.js
index 6c4596a..34353a7 100644
--- a/build/tasks/lib/spawn_test.js
+++ b/build/tasks/lib/spawn_test.js
@@ -1,5 +1,3 @@
-/* jshint node: true */
-
"use strict";
// Run Node with provided parameters: the first one being the Grunt
@@ -7,10 +5,10 @@
// See the comment in ../node_smoke_tests.js for more information.
module.exports = function spawnTest( done ) {
var testPaths = [].slice.call( arguments, 1 ),
- spawn = require( "win-spawn" );
+ spawn = require( "cross-spawn" );
spawn( "node", testPaths, { stdio: "inherit" } )
.on( "close", function( code ) {
done( code === 0 );
} );
-} ;
+};
diff --git a/build/tasks/promises_aplus_tests.js b/build/tasks/promises_aplus_tests.js
index 3e770a0..a0118d1 100644
--- a/build/tasks/promises_aplus_tests.js
+++ b/build/tasks/promises_aplus_tests.js
@@ -4,10 +4,20 @@ module.exports = function( grunt ) {
var spawnTest = require( "./lib/spawn_test.js" );
- grunt.registerTask( "promises_aplus_tests", function() {
+ grunt.registerTask( "promises_aplus_tests",
+ [ "promises_aplus_tests:deferred", "promises_aplus_tests:when" ] );
+
+ grunt.registerTask( "promises_aplus_tests:deferred", function() {
+ spawnTest( this.async(),
+ "./node_modules/.bin/promises-aplus-tests",
+ "test/promises_aplus_adapters/deferred.js"
+ );
+ } );
+
+ grunt.registerTask( "promises_aplus_tests:when", function() {
spawnTest( this.async(),
"./node_modules/.bin/promises-aplus-tests",
- "test/promises_aplus_adapter.js"
+ "test/promises_aplus_adapters/when.js"
);
} );
};
diff --git a/external/sizzle/dist/sizzle.js b/external/sizzle/dist/sizzle.js
index cb93a5b..bfa0793 100644
--- a/external/sizzle/dist/sizzle.js
+++ b/external/sizzle/dist/sizzle.js
@@ -1,12 +1,12 @@
/*!
- * Sizzle CSS Selector Engine v2.3.0
+ * Sizzle CSS Selector Engine v2.3.3
* https://sizzlejs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
- * Date: 2016-01-04
+ * Date: 2016-08-08
*/
(function( window ) {
@@ -152,7 +152,7 @@ var i,
// CSS string/identifier serialization
// https://drafts.csswg.org/cssom/#common-serializing-idioms
- rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
fcssescape = function( ch, asCodePoint ) {
if ( asCodePoint ) {
@@ -179,7 +179,7 @@ var i,
disabledAncestor = addCombinator(
function( elem ) {
- return elem.disabled === true;
+ return elem.disabled === true && ("form" in elem || "label" in elem);
},
{ dir: "parentNode", next: "legend" }
);
@@ -465,26 +465,54 @@ function createButtonPseudo( type ) {
* @param {Boolean} disabled true for :disabled; false for :enabled
*/
function createDisabledPseudo( disabled ) {
- // Known :disabled false positives:
- // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset)
- // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
return function( elem ) {
- // Check form elements and option elements for explicit disabling
- return "label" in elem && elem.disabled === disabled ||
- "form" in elem && elem.disabled === disabled ||
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
+
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
+
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
- // Check non-disabled form elements for fieldset[disabled] ancestors
- "form" in elem && elem.disabled === false && (
- // Support: IE6-11+
- // Ancestry is covered for us
- elem.isDisabled === disabled ||
+ // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
- // Otherwise, assume any non-<option> under fieldset[disabled] is disabled
- /* jshint -W018 */
- elem.isDisabled !== !disabled &&
- ("label" in elem || !disabledAncestor( elem )) !== disabled
- );
+ // Where there is no isDisabled, check manually
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled &&
+ disabledAncestor( elem ) === disabled;
+ }
+
+ return elem.disabled === disabled;
+
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
+
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
};
}
@@ -600,25 +628,21 @@ setDocument = Sizzle.setDocument = function( node ) {
return !document.getElementsByName || !document.getElementsByName( expando ).length;
});
- // ID find and filter
+ // ID filter and find
if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var m = context.getElementById( id );
- return m ? [ m ] : [];
- }
- };
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
return elem.getAttribute("id") === attrId;
};
};
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ };
} else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
@@ -627,6 +651,36 @@ setDocument = Sizzle.setDocument = function( node ) {
return node && node.value === attrId;
};
};
+
+ // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var node, i, elems,
+ elem = context.getElementById( id );
+
+ if ( elem ) {
+
+ // Verify the id attribute
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+
+ // Fall back on getElementsByName
+ elems = context.getElementsByName( id );
+ i = 0;
+ while ( (elem = elems[i++]) ) {
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
}
// Tag
@@ -1667,6 +1721,7 @@ function addCombinator( matcher, combinator, base ) {
return matcher( elem, context, xml );
}
}
+ return false;
} :
// Check against all ancestor/preceding elements
@@ -1711,6 +1766,7 @@ function addCombinator( matcher, combinator, base ) {
}
}
}
+ return false;
};
}
@@ -2073,8 +2129,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
// Reduce context if the leading compound selector is an ID
tokens = match[0] = match[0].slice( 0 );
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 && documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
+ context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
if ( !context ) {
diff --git a/external/sizzle/dist/sizzle.min.js b/external/sizzle/dist/sizzle.min.js
index 7358ad9..be03278 100644
--- a/external/sizzle/dist/sizzle.min.js
+++ b/external/sizzle/dist/sizzle.min.js
@@ -1,3 +1,3 @@
-/*! Sizzle v2.3.0 | (c) jQuery Foundation, Inc. | jquery.org/license */
-!function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\x00-\\xa0])+",M="\\[" [...]
+/*! Sizzle v2.3.3 | (c) jQuery Foundation, Inc. | jquery.org/license */
+!function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K [...]
//# sourceMappingURL=sizzle.min.map
\ No newline at end of file
diff --git a/external/sizzle/dist/sizzle.min.map b/external/sizzle/dist/sizzle.min.map
index d86726d..031c1b7 100644
--- a/external/sizzle/dist/sizzle.min.map
+++ b/external/sizzle/dist/sizzle.min.map
@@ -1 +1 @@
-{"version":3,"sources":["sizzle.js"],"names":["window","i","support","Expr","getText","isXML","tokenize","compile","select","outermostContext","sortInput","hasDuplicate","setDocument","document","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","expando","Date","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","sortOrder","a","b","hasOwn","hasOwnProperty","arr","pop","push_native","push","slice","indexOf","list","elem","len" [...]
\ No newline at end of file
+{"version":3,"sources":["sizzle.js"],"names":["window","i","support","Expr","getText","isXML","tokenize","compile","select","outermostContext","sortInput","hasDuplicate","setDocument","document","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","expando","Date","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","sortOrder","a","b","hasOwn","hasOwnProperty","arr","pop","push_native","push","slice","indexOf","list","elem","len" [...]
\ No newline at end of file
diff --git a/package.json b/package.json
index 7c41aed..b6dd0d3 100644
--- a/package.json
+++ b/package.json
@@ -2,12 +2,12 @@
"name": "jquery",
"title": "jQuery",
"description": "JavaScript library for DOM operations",
- "version": "3.0.0-beta1",
+ "version": "3.1.1",
"main": "dist/jquery.js",
"homepage": "https://jquery.com",
"author": {
"name": "jQuery Foundation and other contributors",
- "url": "https://github.com/jquery/jquery/blob/3.0.0-beta1/AUTHORS.txt"
+ "url": "https://github.com/jquery/jquery/blob/3.1.1/AUTHORS.txt"
},
"repository": {
"type": "git",
@@ -25,44 +25,52 @@
"license": "MIT",
"dependencies": {},
"devDependencies": {
- "commitplease": "2.0.0",
- "core-js": "0.9.17",
- "grunt": "0.4.5",
- "grunt-babel": "5.0.1",
- "grunt-cli": "0.1.13",
- "grunt-compare-size": "0.4.0",
- "grunt-contrib-jshint": "0.11.2",
- "grunt-contrib-uglify": "0.9.2",
- "grunt-contrib-watch": "0.6.1",
- "grunt-git-authors": "2.0.1",
- "grunt-jscs": "2.1.0",
- "grunt-jsonlint": "1.0.4",
+ "babel-preset-es2015": "6.6.0",
+ "commitplease": "2.6.1",
+ "core-js": "2.2.2",
+ "cross-spawn": "2.2.3",
+ "eslint-config-jquery": "1.0.0",
+ "grunt": "1.0.1",
+ "grunt-babel": "6.0.0",
+ "grunt-cli": "1.2.0",
+ "grunt-compare-size": "0.4.2",
+ "grunt-contrib-uglify": "1.0.1",
+ "grunt-contrib-watch": "1.0.0",
+ "grunt-eslint": "19.0.0",
+ "grunt-git-authors": "3.2.0",
+ "grunt-jsonlint": "1.0.7",
+ "grunt-newer": "1.2.0",
"grunt-npmcopy": "0.1.0",
"gzip-js": "0.3.2",
+ "husky": "0.11.4",
+ "insight": "0.8.1",
"jsdom": "5.6.1",
- "load-grunt-tasks": "1.0.0",
- "native-promise-only": "0.7.8-a",
- "promises-aplus-tests": "2.1.0",
- "q": "1.1.2",
- "qunitjs": "1.17.1",
+ "load-grunt-tasks": "3.5.0",
+ "native-promise-only": "0.8.1",
+ "promises-aplus-tests": "2.1.2",
+ "q": "1.4.1",
"qunit-assert-step": "1.0.3",
- "requirejs": "2.1.17",
- "sinon": "1.10.3",
- "sizzle": "2.3.0",
- "strip-json-comments": "1.0.3",
- "testswarm": "1.1.0",
- "win-spawn": "2.0.0"
+ "qunitjs": "1.23.1",
+ "requirejs": "2.2.0",
+ "sinon": "1.17.3",
+ "sizzle": "2.3.3",
+ "strip-json-comments": "2.0.1",
+ "testswarm": "1.1.0"
},
"scripts": {
"build": "npm install && grunt",
"start": "grunt watch",
- "test": "grunt && grunt test"
+ "test": "grunt && grunt test:slow",
+ "precommit": "grunt lint:newer",
+ "commitmsg": "node node_modules/commitplease"
},
"commitplease": {
+ "nohook": true,
"components": [
"Docs",
"Tests",
"Build",
+ "Support",
"Release",
"Core",
"Ajax",
@@ -82,6 +90,8 @@
"Serialize",
"Traversing",
"Wrap"
- ]
+ ],
+ "markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|(refs?)",
+ "ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|(Refs? [^#])"
}
}
diff --git a/src/.eslintrc.json b/src/.eslintrc.json
new file mode 100644
index 0000000..dbf16c5
--- /dev/null
+++ b/src/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ // Support: IE <=9 only, Android <=4.0 only
+ // The above browsers are failing a lot of tests in the ES5
+ // test suite at http://test262.ecmascript.org.
+ "parserOptions": {
+ "ecmaVersion": 3
+ },
+ "globals": {
+ "window": true,
+ "jQuery": true,
+ "define": true,
+ "module": true,
+ "noGlobal": true
+ },
+ "rules": {
+ "strict": ["error", "function"]
+ }
+}
diff --git a/src/.jshintrc b/src/.jshintrc
deleted file mode 100644
index ea3549d..0000000
--- a/src/.jshintrc
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "boss": true,
- "curly": true,
- "eqeqeq": true,
- "eqnull": true,
- "expr": true,
- "immed": true,
- "noarg": true,
- "quotmark": "double",
- "undef": true,
- "unused": true,
-
- "sub": true,
-
- // Support: IE < 10, Android < 4.1
- // The above browsers are failing a lot of tests in the ES5
- // test suite at http://test262.ecmascript.org.
- "es3": true,
-
- "globals": {
- "window": true,
- "JSON": false,
-
- "jQuery": true,
- "define": true,
- "module": true,
- "noGlobal": true
- }
-}
diff --git a/src/ajax.js b/src/ajax.js
index 195a30a..36f707d 100644
--- a/src/ajax.js
+++ b/src/ajax.js
@@ -1,22 +1,24 @@
define( [
"./core",
"./var/document",
- "./var/rnotwhite",
+ "./var/rnothtmlwhite",
"./ajax/var/location",
"./ajax/var/nonce",
"./ajax/var/rquery",
"./core/init",
- "./ajax/parseJSON",
"./ajax/parseXML",
"./event/trigger",
- "./deferred"
-], function( jQuery, document, rnotwhite, location, nonce, rquery ) {
+ "./deferred",
+ "./serialize" // jQuery.param
+], function( jQuery, document, rnothtmlwhite, location, nonce, rquery ) {
+
+"use strict";
var
r20 = /%20/g,
rhash = /#.*$/,
- rts = /([?&])_=[^&]*/,
+ rantiCache = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
// #7653, #8125, #8152: local protocol detection
@@ -62,7 +64,7 @@ function addToPrefiltersOrTransports( structure ) {
var dataType,
i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
+ dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
if ( jQuery.isFunction( func ) ) {
@@ -304,6 +306,7 @@ jQuery.extend( {
processData: true,
async: true,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
/*
timeout: 0,
data: null,
@@ -347,7 +350,7 @@ jQuery.extend( {
"text html": true,
// Evaluate text as a json expression
- "text json": jQuery.parseJSON,
+ "text json": JSON.parse,
// Parse text as xml
"text xml": jQuery.parseXML
@@ -529,18 +532,19 @@ jQuery.extend( {
s.type = options.method || options.type || s.method || s.type;
// Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
+ s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
// A cross-domain request is in order when the origin doesn't match the current origin.
if ( s.crossDomain == null ) {
urlAnchor = document.createElement( "a" );
- // Support: IE8-11+
- // IE throws exception if url is malformed, e.g. http://example.com:80x/
+ // Support: IE <=8 - 11, Edge 12 - 13
+ // IE throws exception on accessing the href property if url is malformed,
+ // e.g. http://example.com:80x/
try {
urlAnchor.href = s.url;
- // Support: IE8-11+
+ // Support: IE <=8 - 11 only
// Anchor's host property isn't correctly set when s.url is relative
urlAnchor.href = urlAnchor.href;
s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
@@ -600,9 +604,9 @@ jQuery.extend( {
delete s.data;
}
- // Add anti-cache in uncached url if needed
+ // Add or update anti-cache param if needed
if ( s.cache === false ) {
- cacheURL = cacheURL.replace( rts, "" );
+ cacheURL = cacheURL.replace( rantiCache, "$1" );
uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
}
diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js
index 666e5d1..8c406e7 100644
--- a/src/ajax/jsonp.js
+++ b/src/ajax/jsonp.js
@@ -5,6 +5,8 @@ define( [
"../ajax"
], function( jQuery, nonce, rquery ) {
+"use strict";
+
var oldCallbacks = [],
rjsonp = /(=)\?(?=&|$)|\?\?/;
diff --git a/src/ajax/load.js b/src/ajax/load.js
index 82f0cf3..3ce3a5a 100644
--- a/src/ajax/load.js
+++ b/src/ajax/load.js
@@ -1,11 +1,14 @@
define( [
"../core",
+ "../core/stripAndCollapse",
"../core/parseHTML",
"../ajax",
"../traversing",
"../manipulation",
"../selector"
-], function( jQuery ) {
+], function( jQuery, stripAndCollapse ) {
+
+"use strict";
/**
* Load a url into a page
@@ -16,7 +19,7 @@ jQuery.fn.load = function( url, params, callback ) {
off = url.indexOf( " " );
if ( off > -1 ) {
- selector = jQuery.trim( url.slice( off ) );
+ selector = stripAndCollapse( url.slice( off ) );
url = url.slice( 0, off );
}
@@ -62,7 +65,7 @@ jQuery.fn.load = function( url, params, callback ) {
// If it fails, this function gets "jqXHR", "status", "error"
} ).always( callback && function( jqXHR, status ) {
self.each( function() {
- callback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] );
+ callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
} );
} );
}
diff --git a/src/ajax/parseJSON.js b/src/ajax/parseJSON.js
deleted file mode 100644
index c2aeb6a..0000000
--- a/src/ajax/parseJSON.js
+++ /dev/null
@@ -1,9 +0,0 @@
-define( [
- "../core"
-], function( jQuery ) {
-
-jQuery.parseJSON = JSON.parse;
-
-return jQuery.parseJSON;
-
-} );
diff --git a/src/ajax/parseXML.js b/src/ajax/parseXML.js
index 6599aaf..acf7ab2 100644
--- a/src/ajax/parseXML.js
+++ b/src/ajax/parseXML.js
@@ -2,6 +2,8 @@ define( [
"../core"
], function( jQuery ) {
+"use strict";
+
// Cross-browser xml parsing
jQuery.parseXML = function( data ) {
var xml;
@@ -9,7 +11,8 @@ jQuery.parseXML = function( data ) {
return null;
}
- // Support: IE9
+ // Support: IE 9 - 11 only
+ // IE throws on parseFromString with invalid input.
try {
xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
} catch ( e ) {
diff --git a/src/ajax/script.js b/src/ajax/script.js
index 485ba39..6e0d21e 100644
--- a/src/ajax/script.js
+++ b/src/ajax/script.js
@@ -4,6 +4,8 @@ define( [
"../ajax"
], function( jQuery, document ) {
+"use strict";
+
// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
jQuery.ajaxPrefilter( function( s ) {
if ( s.crossDomain ) {
diff --git a/src/ajax/var/location.js b/src/ajax/var/location.js
index ff9578e..4171d18 100644
--- a/src/ajax/var/location.js
+++ b/src/ajax/var/location.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return window.location;
} );
diff --git a/src/ajax/var/nonce.js b/src/ajax/var/nonce.js
index 83fd557..6e23708 100644
--- a/src/ajax/var/nonce.js
+++ b/src/ajax/var/nonce.js
@@ -1,5 +1,7 @@
define( [
"../../core"
], function( jQuery ) {
+ "use strict";
+
return jQuery.now();
} );
diff --git a/src/ajax/var/rquery.js b/src/ajax/var/rquery.js
index 0502146..06fc374 100644
--- a/src/ajax/var/rquery.js
+++ b/src/ajax/var/rquery.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /\?/ );
} );
diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js
index db670ff..33dafb0 100644
--- a/src/ajax/xhr.js
+++ b/src/ajax/xhr.js
@@ -4,6 +4,8 @@ define( [
"../ajax"
], function( jQuery, support ) {
+"use strict";
+
jQuery.ajaxSettings.xhr = function() {
try {
return new window.XMLHttpRequest();
@@ -15,7 +17,7 @@ var xhrSuccessStatus = {
// File protocol always yields status code 0, assume 200
0: 200,
- // Support: IE9
+ // Support: IE <=9 only
// #1450: sometimes IE returns 1223 when it should be 204
1223: 204
},
@@ -79,7 +81,7 @@ jQuery.ajaxTransport( function( options ) {
xhr.abort();
} else if ( type === "error" ) {
- // Support: IE9
+ // Support: IE <=9 only
// On a manual native abort, IE9 throws
// errors on any property access that is not readyState
if ( typeof xhr.status !== "number" ) {
@@ -97,7 +99,7 @@ jQuery.ajaxTransport( function( options ) {
xhrSuccessStatus[ xhr.status ] || xhr.status,
xhr.statusText,
- // Support: IE9 only
+ // Support: IE <=9 only
// IE9 has no XHR2 but throws on binary (trac-11426)
// For XHR2 non-text, let the caller handle it (gh-2498)
( xhr.responseType || "text" ) !== "text" ||
@@ -115,7 +117,7 @@ jQuery.ajaxTransport( function( options ) {
xhr.onload = callback();
errorCallback = xhr.onerror = callback( "error" );
- // Support: IE9
+ // Support: IE 9 only
// Use onreadystatechange to replace onabort
// to handle uncaught aborts
if ( xhr.onabort !== undefined ) {
diff --git a/src/attributes.js b/src/attributes.js
index 691e0c0..2d801e5 100644
--- a/src/attributes.js
+++ b/src/attributes.js
@@ -6,6 +6,8 @@ define( [
"./attributes/val"
], function( jQuery ) {
+"use strict";
+
// Return jQuery for attributes-only inclusion
return jQuery;
} );
diff --git a/src/attributes/attr.js b/src/attributes/attr.js
index 00b0848..2d9c76f 100644
--- a/src/attributes/attr.js
+++ b/src/attributes/attr.js
@@ -2,19 +2,14 @@ define( [
"../core",
"../core/access",
"./support",
- "../var/rnotwhite",
+ "../var/rnothtmlwhite",
"../selector"
-], function( jQuery, access, support, rnotwhite ) {
+], function( jQuery, access, support, rnothtmlwhite ) {
-var boolHook,
- attrHandle = jQuery.expr.attrHandle,
+"use strict";
- // Exclusively lowercase A-Z in attribute names (gh-2730)
- // https://dom.spec.whatwg.org/#converted-to-ascii-lowercase
- raz = /[A-Z]+/g,
- lowercase = function( ch ) {
- return ch.toLowerCase();
- };
+var boolHook,
+ attrHandle = jQuery.expr.attrHandle;
jQuery.fn.extend( {
attr: function( name, value ) {
@@ -43,11 +38,10 @@ jQuery.extend( {
return jQuery.prop( elem, name, value );
}
- // All attributes are lowercase
+ // Attribute hooks are determined by the lowercase version
// Grab necessary hook if one is defined
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- name = name.replace( raz, lowercase );
- hooks = jQuery.attrHooks[ name ] ||
+ hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
}
@@ -95,7 +89,10 @@ jQuery.extend( {
removeAttr: function( elem, value ) {
var name,
i = 0,
- attrNames = value && value.match( rnotwhite );
+
+ // Attribute names can contain non-HTML whitespace characters
+ // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+ attrNames = value && value.match( rnothtmlwhite );
if ( attrNames && elem.nodeType === 1 ) {
while ( ( name = attrNames[ i++ ] ) ) {
@@ -123,16 +120,18 @@ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name )
var getter = attrHandle[ name ] || jQuery.find.attr;
attrHandle[ name ] = function( elem, name, isXML ) {
- var ret, handle;
+ var ret, handle,
+ lowercaseName = name.toLowerCase();
+
if ( !isXML ) {
// Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
+ handle = attrHandle[ lowercaseName ];
+ attrHandle[ lowercaseName ] = ret;
ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
+ lowercaseName :
null;
- attrHandle[ name ] = handle;
+ attrHandle[ lowercaseName ] = handle;
}
return ret;
};
diff --git a/src/attributes/classes.js b/src/attributes/classes.js
index 7933873..23b4cd6 100644
--- a/src/attributes/classes.js
+++ b/src/attributes/classes.js
@@ -1,11 +1,12 @@
define( [
"../core",
- "../var/rnotwhite",
+ "../core/stripAndCollapse",
+ "../var/rnothtmlwhite",
"../data/var/dataPriv",
"../core/init"
-], function( jQuery, rnotwhite, dataPriv ) {
+], function( jQuery, stripAndCollapse, rnothtmlwhite, dataPriv ) {
-var rclass = /[\t\r\n\f]/g;
+"use strict";
function getClass( elem ) {
return elem.getAttribute && elem.getAttribute( "class" ) || "";
@@ -23,12 +24,11 @@ jQuery.fn.extend( {
}
if ( typeof value === "string" && value ) {
- classes = value.match( rnotwhite ) || [];
+ classes = value.match( rnothtmlwhite ) || [];
while ( ( elem = this[ i++ ] ) ) {
curValue = getClass( elem );
- cur = elem.nodeType === 1 &&
- ( " " + curValue + " " ).replace( rclass, " " );
+ cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
if ( cur ) {
j = 0;
@@ -39,7 +39,7 @@ jQuery.fn.extend( {
}
// Only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
+ finalValue = stripAndCollapse( cur );
if ( curValue !== finalValue ) {
elem.setAttribute( "class", finalValue );
}
@@ -65,14 +65,13 @@ jQuery.fn.extend( {
}
if ( typeof value === "string" && value ) {
- classes = value.match( rnotwhite ) || [];
+ classes = value.match( rnothtmlwhite ) || [];
while ( ( elem = this[ i++ ] ) ) {
curValue = getClass( elem );
// This expression is here for better compressibility (see addClass)
- cur = elem.nodeType === 1 &&
- ( " " + curValue + " " ).replace( rclass, " " );
+ cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
if ( cur ) {
j = 0;
@@ -85,7 +84,7 @@ jQuery.fn.extend( {
}
// Only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
+ finalValue = stripAndCollapse( cur );
if ( curValue !== finalValue ) {
elem.setAttribute( "class", finalValue );
}
@@ -120,7 +119,7 @@ jQuery.fn.extend( {
// Toggle individual class names
i = 0;
self = jQuery( this );
- classNames = value.match( rnotwhite ) || [];
+ classNames = value.match( rnothtmlwhite ) || [];
while ( ( className = classNames[ i++ ] ) ) {
@@ -163,10 +162,8 @@ jQuery.fn.extend( {
className = " " + selector + " ";
while ( ( elem = this[ i++ ] ) ) {
if ( elem.nodeType === 1 &&
- ( " " + getClass( elem ) + " " ).replace( rclass, " " )
- .indexOf( className ) > -1
- ) {
- return true;
+ ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+ return true;
}
}
diff --git a/src/attributes/prop.js b/src/attributes/prop.js
index da7bc1e..49ac244 100644
--- a/src/attributes/prop.js
+++ b/src/attributes/prop.js
@@ -5,6 +5,8 @@ define( [
"../selector"
], function( jQuery, access, support ) {
+"use strict";
+
var rfocusable = /^(?:input|select|textarea|button)$/i,
rclickable = /^(?:a|area)$/i;
@@ -57,18 +59,26 @@ jQuery.extend( {
tabIndex: {
get: function( elem ) {
+ // Support: IE <=9 - 11 only
// elem.tabIndex doesn't always return the
// correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
// Use proper attribute retrieval(#12072)
var tabindex = jQuery.find.attr( elem, "tabindex" );
- return tabindex ?
- parseInt( tabindex, 10 ) :
+ if ( tabindex ) {
+ return parseInt( tabindex, 10 );
+ }
+
+ if (
rfocusable.test( elem.nodeName ) ||
- rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- -1;
+ rclickable.test( elem.nodeName ) &&
+ elem.href
+ ) {
+ return 0;
+ }
+
+ return -1;
}
}
},
@@ -79,14 +89,38 @@ jQuery.extend( {
}
} );
+// Support: IE <=11 only
+// Accessing the selectedIndex property
+// forces the browser to respect setting selected
+// on the option
+// The getter ensures a default option is selected
+// when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
if ( !support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
+
+ /* eslint no-unused-expressions: "off" */
+
var parent = elem.parentNode;
if ( parent && parent.parentNode ) {
parent.parentNode.selectedIndex;
}
return null;
+ },
+ set: function( elem ) {
+
+ /* eslint no-unused-expressions: "off" */
+
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
}
};
}
diff --git a/src/attributes/support.js b/src/attributes/support.js
index f93ba01..af60e96 100644
--- a/src/attributes/support.js
+++ b/src/attributes/support.js
@@ -3,6 +3,8 @@ define( [
"../var/support"
], function( document, support ) {
+"use strict";
+
( function() {
var input = document.createElement( "input" ),
select = document.createElement( "select" ),
@@ -10,15 +12,15 @@ define( [
input.type = "checkbox";
- // Support: Android<4.4
+ // Support: Android <=4.3 only
// Default value for a checkbox should be "on"
support.checkOn = input.value !== "";
- // Support: IE<=11+
+ // Support: IE <=11 only
// Must access selectedIndex to make default options select
support.optSelected = opt.selected;
- // Support: IE<=11+
+ // Support: IE <=11 only
// An input loses its value after becoming a radio
input = document.createElement( "input" );
input.value = "t";
diff --git a/src/attributes/val.js b/src/attributes/val.js
index 5f0b73e..fbf4069 100644
--- a/src/attributes/val.js
+++ b/src/attributes/val.js
@@ -1,8 +1,11 @@
define( [
"../core",
+ "../core/stripAndCollapse",
"./support",
"../core/init"
-], function( jQuery, support ) {
+], function( jQuery, stripAndCollapse, support ) {
+
+"use strict";
var rreturn = /\r/g;
@@ -25,13 +28,13 @@ jQuery.fn.extend( {
ret = elem.value;
- return typeof ret === "string" ?
-
- // Handle most common string cases
- ret.replace( rreturn, "" ) :
+ // Handle most common string cases
+ if ( typeof ret === "string" ) {
+ return ret.replace( rreturn, "" );
+ }
- // Handle cases where value is null/undef or number
- ret == null ? "" : ret;
+ // Handle cases where value is null/undef or number
+ return ret == null ? "" : ret;
}
return;
@@ -80,27 +83,38 @@ jQuery.extend( {
option: {
get: function( elem ) {
- // Support: IE<11
- // option.value not trimmed (#14858)
- return jQuery.trim( elem.value );
+ var val = jQuery.find.attr( elem, "value" );
+ return val != null ?
+ val :
+
+ // Support: IE <=10 - 11 only
+ // option.text throws exceptions (#14686, #14858)
+ // Strip and collapse whitespace
+ // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+ stripAndCollapse( jQuery.text( elem ) );
}
},
select: {
get: function( elem ) {
- var value, option,
+ var value, option, i,
options = elem.options,
index = elem.selectedIndex,
one = elem.type === "select-one",
values = one ? null : [],
- max = one ? index + 1 : options.length,
- i = index < 0 ?
- max :
- one ? index : 0;
+ max = one ? index + 1 : options.length;
+
+ if ( index < 0 ) {
+ i = max;
+
+ } else {
+ i = one ? index : 0;
+ }
// Loop through all the selected options
for ( ; i < max; i++ ) {
option = options[ i ];
+ // Support: IE <=9 only
// IE8-9 doesn't update selected after form reset (#2551)
if ( ( option.selected || i === index ) &&
@@ -133,11 +147,16 @@ jQuery.extend( {
while ( i-- ) {
option = options[ i ];
+
+ /* eslint-disable no-cond-assign */
+
if ( option.selected =
- jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
+ jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
) {
optionSet = true;
}
+
+ /* eslint-enable no-cond-assign */
}
// Force browsers to behave consistently when non-matching value is set
diff --git a/src/callbacks.js b/src/callbacks.js
index b032c8f..a6d4df0 100644
--- a/src/callbacks.js
+++ b/src/callbacks.js
@@ -1,12 +1,14 @@
define( [
"./core",
- "./var/rnotwhite"
-], function( jQuery, rnotwhite ) {
+ "./var/rnothtmlwhite"
+], function( jQuery, rnothtmlwhite ) {
+
+"use strict";
// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
var object = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+ jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
object[ flag ] = true;
} );
return object;
diff --git a/src/core.js b/src/core.js
index 3a54ffc..4c8a4ab 100644
--- a/src/core.js
+++ b/src/core.js
@@ -1,6 +1,11 @@
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
define( [
"./var/arr",
"./var/document",
+ "./var/getProto",
"./var/slice",
"./var/concat",
"./var/push",
@@ -8,13 +13,18 @@ define( [
"./var/class2type",
"./var/toString",
"./var/hasOwn",
+ "./var/fnToString",
+ "./var/ObjectFunctionString",
"./var/support",
"./core/DOMEval"
-], function( arr, document, slice, concat,
- push, indexOf, class2type, toString, hasOwn, support, DOMEval ) {
+], function( arr, document, getProto, slice, concat, push, indexOf,
+ class2type, toString, hasOwn, fnToString, ObjectFunctionString,
+ support, DOMEval ) {
+
+"use strict";
var
- version = "@VERSION",
+ version = "3.1.1",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
@@ -24,7 +34,7 @@ var
return new jQuery.fn.init( selector, context );
},
- // Support: Android<4.1
+ // Support: Android <=4.0 only
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
@@ -54,13 +64,14 @@ jQuery.fn = jQuery.prototype = {
// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
- return num != null ?
- // Return just the one element from the set
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+ // Return all the elements in a clean array
+ if ( num == null ) {
+ return slice.call( this );
+ }
- // Return all the elements in a clean array
- slice.call( this );
+ // Return just the one element from the set
+ return num < 0 ? this[ num + this.length ] : this[ num ];
},
// Take an array of elements and push it onto the stack
@@ -217,31 +228,40 @@ jQuery.extend( {
// that can be coerced to finite numbers (gh-2662)
var type = jQuery.type( obj );
return ( type === "number" || type === "string" ) &&
- ( obj - parseFloat( obj ) + 1 ) >= 0;
+
+ // parseFloat NaNs numeric-cast false positives ("")
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+ // subtraction forces infinities to NaN
+ !isNaN( obj - parseFloat( obj ) );
},
isPlainObject: function( obj ) {
+ var proto, Ctor;
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+ if ( !obj || toString.call( obj ) !== "[object Object]" ) {
return false;
}
- if ( obj.constructor &&
- !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
- return false;
+ proto = getProto( obj );
+
+ // Objects with no prototype (e.g., `Object.create( null )`) are plain
+ if ( !proto ) {
+ return true;
}
- // If the function hasn't returned already, we're confident that
- // |obj| is a plain object, created by {} or constructed with new Object
- return true;
+ // Objects with prototype are plain iff they were constructed by a global Object function
+ Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
},
isEmptyObject: function( obj ) {
+
+ /* eslint-disable no-unused-vars */
+ // See https://github.com/eslint/eslint/issues/6125
var name;
+
for ( name in obj ) {
return false;
}
@@ -253,7 +273,7 @@ jQuery.extend( {
return obj + "";
}
- // Support: Android<4.0 (functionish RegExp)
+ // Support: Android <=2.3 only (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call( obj ) ] || "object" :
typeof obj;
@@ -265,7 +285,7 @@ jQuery.extend( {
},
// Convert dashed to camelCase; used by the css and data modules
- // Support: IE9-11+
+ // Support: IE <=9 - 11, Edge 12 - 13
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
@@ -296,7 +316,7 @@ jQuery.extend( {
return obj;
},
- // Support: Android<4.1
+ // Support: Android <=4.0 only
trim: function( text ) {
return text == null ?
"" :
@@ -325,7 +345,7 @@ jQuery.extend( {
return arr == null ? -1 : indexOf.call( arr, elem, i );
},
- // Support: Android<4.1, PhantomJS<2
+ // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
merge: function( first, second ) {
var len = +second.length,
@@ -431,15 +451,9 @@ jQuery.extend( {
support: support
} );
-// JSHint would error on this code due to the Symbol not being defined in ES5.
-// Defining this global in .jshintrc would create a danger of using the global
-// unguarded in another place, it seems safer to just disable JSHint for these
-// three lines.
-/* jshint ignore: start */
if ( typeof Symbol === "function" ) {
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}
-/* jshint ignore: end */
// Populate the class2type map
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
@@ -449,7 +463,7 @@ function( i, name ) {
function isArrayLike( obj ) {
- // Support: iOS 8.2 (not reproducible in simulator)
+ // Support: real iOS 8.2 only (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
diff --git a/src/core/DOMEval.js b/src/core/DOMEval.js
index 222b0ca..c49c12e 100644
--- a/src/core/DOMEval.js
+++ b/src/core/DOMEval.js
@@ -1,6 +1,8 @@
define( [
"../var/document"
], function( document ) {
+ "use strict";
+
function DOMEval( code, doc ) {
doc = doc || document;
diff --git a/src/core/access.js b/src/core/access.js
index 19f79ef..86cdbc7 100644
--- a/src/core/access.js
+++ b/src/core/access.js
@@ -2,6 +2,8 @@ define( [
"../core"
], function( jQuery ) {
+"use strict";
+
// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
@@ -51,13 +53,16 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
}
}
- return chainable ?
- elems :
+ if ( chainable ) {
+ return elems;
+ }
+
+ // Gets
+ if ( bulk ) {
+ return fn.call( elems );
+ }
- // Gets
- bulk ?
- fn.call( elems ) :
- len ? fn( elems[ 0 ], key ) : emptyGet;
+ return len ? fn( elems[ 0 ], key ) : emptyGet;
};
return access;
diff --git a/src/core/init.js b/src/core/init.js
index a00d587..19a3c7c 100644
--- a/src/core/init.js
+++ b/src/core/init.js
@@ -6,6 +6,8 @@ define( [
"../traversing/findFilter"
], function( jQuery, document, rsingleTag ) {
+"use strict";
+
// A central reference to the root jQuery(document)
var rootjQuery,
diff --git a/src/core/parseHTML.js b/src/core/parseHTML.js
index 3040536..21ff6bf 100644
--- a/src/core/parseHTML.js
+++ b/src/core/parseHTML.js
@@ -8,6 +8,8 @@ define( [
"./support"
], function( jQuery, document, rsingleTag, buildFragment, support ) {
+"use strict";
+
// Argument "data" should be string of html
// context (optional): If specified, the fragment will be created in this context,
// defaults to document
@@ -21,14 +23,28 @@ jQuery.parseHTML = function( data, context, keepScripts ) {
context = false;
}
- // Stop scripts or inline event handlers from being executed immediately
- // by using document.implementation
- context = context || ( support.createHTMLDocument ?
- document.implementation.createHTMLDocument( "" ) :
- document );
+ var base, parsed, scripts;
+
+ if ( !context ) {
+
+ // Stop scripts or inline event handlers from being executed immediately
+ // by using document.implementation
+ if ( support.createHTMLDocument ) {
+ context = document.implementation.createHTMLDocument( "" );
+
+ // Set the base href for the created document
+ // so any parsed elements with URLs
+ // are based on the document's URL (gh-2965)
+ base = context.createElement( "base" );
+ base.href = document.location.href;
+ context.head.appendChild( base );
+ } else {
+ context = document;
+ }
+ }
- var parsed = rsingleTag.exec( data ),
- scripts = !keepScripts && [];
+ parsed = rsingleTag.exec( data );
+ scripts = !keepScripts && [];
// Single tag
if ( parsed ) {
diff --git a/src/core/ready-no-deferred.js b/src/core/ready-no-deferred.js
new file mode 100644
index 0000000..02d6014
--- /dev/null
+++ b/src/core/ready-no-deferred.js
@@ -0,0 +1,105 @@
+define( [
+ "../core",
+ "../var/document"
+], function( jQuery, document ) {
+
+"use strict";
+
+var readyCallbacks = [],
+ whenReady = function( fn ) {
+ readyCallbacks.push( fn );
+ },
+ executeReady = function( fn ) {
+
+ // Prevent errors from freezing future callback execution (gh-1823)
+ // Not backwards-compatible as this does not execute sync
+ window.setTimeout( function() {
+ fn.call( document, jQuery );
+ } );
+ };
+
+jQuery.fn.ready = function( fn ) {
+ whenReady( 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 );
+ }
+ },
+
+ 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;
+ }
+
+ whenReady = function( fn ) {
+ readyCallbacks.push( fn );
+
+ while ( readyCallbacks.length ) {
+ fn = readyCallbacks.shift();
+ if ( jQuery.isFunction( fn ) ) {
+ executeReady( fn );
+ }
+ }
+ };
+
+ whenReady();
+ }
+} );
+
+// Make jQuery.ready Promise consumable (gh-1778)
+jQuery.ready.then = jQuery.fn.ready;
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE9-10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+} else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+}
+
+} );
diff --git a/src/core/ready.js b/src/core/ready.js
index 73c3d70..53b1b2d 100644
--- a/src/core/ready.js
+++ b/src/core/ready.js
@@ -1,16 +1,26 @@
define( [
"../core",
"../var/document",
+ "../core/readyException",
"../deferred"
], function( jQuery, document ) {
+"use strict";
+
// The deferred used on DOM ready
-var readyList;
+var readyList = jQuery.Deferred();
jQuery.fn.ready = function( fn ) {
- // Add the callback
- jQuery.ready.promise().done( fn );
+ readyList
+ .then( fn )
+
+ // Wrap jQuery.readyException in a function so that the lookup
+ // happens at the time of error handling instead of callback
+ // registration.
+ .catch( function( error ) {
+ jQuery.readyException( error );
+ } );
return this;
};
@@ -54,43 +64,32 @@ jQuery.extend( {
}
} );
-/**
- * The ready event handler and self cleanup method
- */
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
function completed() {
document.removeEventListener( "DOMContentLoaded", completed );
window.removeEventListener( "load", completed );
jQuery.ready();
}
-jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
- readyList = jQuery.Deferred();
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
- // Catch cases where $(document).ready() is called
- // after the browser event has already occurred.
- // Support: IE9-10 only
- // Older IE sometimes signals "interactive" too soon
- if ( document.readyState === "complete" ||
- ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- window.setTimeout( jQuery.ready );
-
- } else {
+} else {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed );
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed );
- }
- }
- return readyList.promise( obj );
-};
-
-// Kick off the DOM ready check even if the user does not
-jQuery.ready.promise();
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+}
} );
diff --git a/src/core/readyException.js b/src/core/readyException.js
new file mode 100644
index 0000000..72bdd90
--- /dev/null
+++ b/src/core/readyException.js
@@ -0,0 +1,13 @@
+define( [
+ "../core"
+], function( jQuery ) {
+
+"use strict";
+
+jQuery.readyException = function( error ) {
+ window.setTimeout( function() {
+ throw error;
+ } );
+};
+
+} );
diff --git a/src/core/stripAndCollapse.js b/src/core/stripAndCollapse.js
new file mode 100644
index 0000000..ccad660
--- /dev/null
+++ b/src/core/stripAndCollapse.js
@@ -0,0 +1,14 @@
+define( [
+ "../var/rnothtmlwhite"
+], function( rnothtmlwhite ) {
+ "use strict";
+
+ // Strip and collapse whitespace according to HTML spec
+ // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
+ function stripAndCollapse( value ) {
+ var tokens = value.match( rnothtmlwhite ) || [];
+ return tokens.join( " " );
+ }
+
+ return stripAndCollapse;
+} );
diff --git a/src/core/support.js b/src/core/support.js
index 0609a70..13ae02f 100644
--- a/src/core/support.js
+++ b/src/core/support.js
@@ -3,7 +3,9 @@ define( [
"../var/support"
], function( document, support ) {
-// Support: Safari 8+
+"use strict";
+
+// Support: Safari 8 only
// In Safari 8 documents created via document.implementation.createHTMLDocument
// collapse sibling forms: the second one becomes a child of the first one.
// Because of that, this security measure has to be disabled in Safari 8.
diff --git a/src/core/var/rsingleTag.js b/src/core/var/rsingleTag.js
index 1ddf95e..4d6e8a0 100644
--- a/src/core/var/rsingleTag.js
+++ b/src/core/var/rsingleTag.js
@@ -1,4 +1,5 @@
define( function() {
+ "use strict";
// Match a standalone tag
return ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
diff --git a/src/css.js b/src/css.js
index 5d3a0a6..5e44511 100644
--- a/src/css.js
+++ b/src/css.js
@@ -7,7 +7,6 @@ define( [
"./var/rcssNum",
"./css/var/rnumnonpx",
"./css/var/cssExpand",
- "./css/var/isHidden",
"./css/var/getStyles",
"./css/var/swap",
"./css/curCSS",
@@ -19,7 +18,9 @@ define( [
"./core/ready",
"./selector" // contains
], function( jQuery, pnum, access, rmargin, document, rcssNum, rnumnonpx, cssExpand,
- isHidden, getStyles, swap, curCSS, adjustCSS, addGetHookIf, support ) {
+ getStyles, swap, curCSS, adjustCSS, addGetHookIf, support ) {
+
+"use strict";
var
@@ -69,15 +70,17 @@ function setPositiveNumber( elem, value, subtract ) {
}
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
-
- // If we already have the right measurement, avoid augmentation
- 4 :
+ var i,
+ val = 0;
- // Otherwise initialize for horizontal or vertical properties
- name === "width" ? 1 : 0,
+ // If we already have the right measurement, avoid augmentation
+ if ( extra === ( isBorderBox ? "border" : "content" ) ) {
+ i = 4;
- val = 0;
+ // Otherwise initialize for horizontal or vertical properties
+ } else {
+ i = name === "width" ? 1 : 0;
+ }
for ( ; i < 4; i += 2 ) {
@@ -120,20 +123,13 @@ function getWidthOrHeight( elem, name, extra ) {
styles = getStyles( elem ),
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
- // Support: IE <= 11 only
+ // Support: IE <=11 only
// Running getBoundingClientRect on a disconnected node
// in IE throws an error.
if ( elem.getClientRects().length ) {
val = elem.getBoundingClientRect()[ name ];
}
- // Support: IE11 only
- // In IE 11 fullscreen elements inside of an iframe have
- // 100x too small dimensions (gh-1764).
- if ( document.msFullscreenElement && window.top !== window ) {
- val *= 100;
- }
-
// Some non-html elements return undefined for offsetWidth, so check for null/undefined
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
@@ -252,7 +248,6 @@ jQuery.extend( {
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
}
- // Support: IE9-11+
// background-* props affect original clone's values
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
style[ name ] = "inherit";
@@ -326,7 +321,7 @@ jQuery.each( [ "height", "width" ], function( i, name ) {
// Support: Safari 8+
// Table columns in Safari have non-zero offsetWidth & zero
// getBoundingClientRect().width unless display is changed.
- // Support: IE <= 11 only
+ // Support: IE <=11 only
// Running getBoundingClientRect on a disconnected node
// in IE throws an error.
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
diff --git a/src/css/addGetHookIf.js b/src/css/addGetHookIf.js
index 9cd21f6..e4bb49a 100644
--- a/src/css/addGetHookIf.js
+++ b/src/css/addGetHookIf.js
@@ -1,5 +1,7 @@
define( function() {
+"use strict";
+
function addGetHookIf( conditionFn, hookFn ) {
// Define the hook, we'll check on the first run if it's really needed.
diff --git a/src/css/adjustCSS.js b/src/css/adjustCSS.js
index 48fcfec..ded3a16 100644
--- a/src/css/adjustCSS.js
+++ b/src/css/adjustCSS.js
@@ -3,13 +3,19 @@ define( [
"../var/rcssNum"
], function( jQuery, rcssNum ) {
+"use strict";
+
function adjustCSS( elem, prop, valueParts, tween ) {
var adjusted,
scale = 1,
maxIterations = 20,
currentValue = tween ?
- function() { return tween.cur(); } :
- function() { return jQuery.css( elem, prop, "" ); },
+ function() {
+ return tween.cur();
+ } :
+ function() {
+ return jQuery.css( elem, prop, "" );
+ },
initial = currentValue(),
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
diff --git a/src/css/curCSS.js b/src/css/curCSS.js
index be643ab..313da42 100644
--- a/src/css/curCSS.js
+++ b/src/css/curCSS.js
@@ -7,13 +7,15 @@ define( [
"../selector" // Get jQuery.contains
], function( jQuery, rnumnonpx, rmargin, getStyles, support ) {
+"use strict";
+
function curCSS( elem, name, computed ) {
var width, minWidth, maxWidth, ret,
style = elem.style;
computed = computed || getStyles( elem );
- // Support: IE9
+ // Support: IE <=9 only
// getPropertyValue is only needed for .css('filter') (#12537)
if ( computed ) {
ret = computed.getPropertyValue( name ) || computed[ name ];
@@ -26,7 +28,7 @@ function curCSS( elem, name, computed ) {
// Android Browser returns percentage for some values,
// but width seems to be reliably pixels.
// This is against the CSSOM draft spec:
- // http://dev.w3.org/csswg/cssom/#resolved-values
+ // https://drafts.csswg.org/cssom/#resolved-values
if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
// Remember the original values
@@ -47,7 +49,7 @@ function curCSS( elem, name, computed ) {
return ret !== undefined ?
- // Support: IE9-11+
+ // Support: IE <=9 - 11 only
// IE returns zIndex value as an integer.
ret + "" :
ret;
diff --git a/src/css/hiddenVisibleSelectors.js b/src/css/hiddenVisibleSelectors.js
index 9a8a28c..d7a9339 100644
--- a/src/css/hiddenVisibleSelectors.js
+++ b/src/css/hiddenVisibleSelectors.js
@@ -3,10 +3,12 @@ define( [
"../selector"
], function( jQuery ) {
-jQuery.expr.filters.hidden = function( elem ) {
- return !jQuery.expr.filters.visible( elem );
+"use strict";
+
+jQuery.expr.pseudos.hidden = function( elem ) {
+ return !jQuery.expr.pseudos.visible( elem );
};
-jQuery.expr.filters.visible = function( elem ) {
+jQuery.expr.pseudos.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};
diff --git a/src/css/showHide.js b/src/css/showHide.js
index 9e2cb1e..3eeafef 100644
--- a/src/css/showHide.js
+++ b/src/css/showHide.js
@@ -1,8 +1,10 @@
define( [
"../core",
"../data/var/dataPriv",
- "../css/var/isHidden"
-], function( jQuery, dataPriv, isHidden ) {
+ "../css/var/isHiddenWithinTree"
+], function( jQuery, dataPriv, isHiddenWithinTree ) {
+
+"use strict";
var defaultDisplayMap = {};
@@ -16,7 +18,7 @@ function getDefaultDisplay( elem ) {
return display;
}
- temp = doc.body.appendChild( doc.createElement( nodeName ) ),
+ temp = doc.body.appendChild( doc.createElement( nodeName ) );
display = jQuery.css( temp, "display" );
temp.parentNode.removeChild( temp );
@@ -54,12 +56,7 @@ function showHide( elements, show ) {
elem.style.display = "";
}
}
- if ( elem.style.display === "" && jQuery.css( elem, "display" ) === "none" &&
-
- // Support: Firefox <=42 - 43
- // Don't set inline display on disconnected elements with computed display: none
- jQuery.contains( elem.ownerDocument, elem ) ) {
-
+ if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
values[ index ] = getDefaultDisplay( elem );
}
} else {
@@ -95,7 +92,7 @@ jQuery.fn.extend( {
}
return this.each( function() {
- if ( isHidden( this ) ) {
+ if ( isHiddenWithinTree( this ) ) {
jQuery( this ).show();
} else {
jQuery( this ).hide();
diff --git a/src/css/support.js b/src/css/support.js
index f8e02d0..883d0e5 100644
--- a/src/css/support.js
+++ b/src/css/support.js
@@ -5,29 +5,19 @@ define( [
"../var/support"
], function( jQuery, document, documentElement, support ) {
-( function() {
- var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
- container = document.createElement( "div" ),
- div = document.createElement( "div" );
-
- // Finish early in limited (non-browser) environments
- if ( !div.style ) {
- return;
- }
-
- // Support: IE9-11+
- // Style of cloned element affects source element cloned (#8908)
- div.style.backgroundClip = "content-box";
- div.cloneNode( true ).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
+"use strict";
- container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
- "padding:0;margin-top:1px;position:absolute";
- container.appendChild( div );
+( function() {
// Executing both pixelPosition & boxSizingReliable tests require only one layout
// so they're executed at the same time to save the second computation.
function computeStyleTests() {
+
+ // This is a singleton, we need to execute it only once
+ if ( !div ) {
+ return;
+ }
+
div.style.cssText =
"box-sizing:border-box;" +
"position:relative;display:block;" +
@@ -38,6 +28,8 @@ define( [
var divStyle = window.getComputedStyle( div );
pixelPositionVal = divStyle.top !== "1%";
+
+ // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
reliableMarginLeftVal = divStyle.marginLeft === "2px";
boxSizingReliableVal = divStyle.width === "4px";
@@ -47,39 +39,46 @@ define( [
pixelMarginRightVal = divStyle.marginRight === "4px";
documentElement.removeChild( container );
+
+ // Nullify the div so it wouldn't be stored in the memory and
+ // it will also be a sign that checks already performed
+ div = null;
}
+ var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
+ container = document.createElement( "div" ),
+ div = document.createElement( "div" );
+
+ // Finish early in limited (non-browser) environments
+ if ( !div.style ) {
+ return;
+ }
+
+ // Support: IE <=9 - 11 only
+ // Style of cloned element affects source element cloned (#8908)
+ div.style.backgroundClip = "content-box";
+ div.cloneNode( true ).style.backgroundClip = "";
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+ container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+ "padding:0;margin-top:1px;position:absolute";
+ container.appendChild( div );
+
jQuery.extend( support, {
pixelPosition: function() {
-
- // This test is executed only once but we still do memoizing
- // since we can use the boxSizingReliable pre-computing.
- // No need to check if the test was already performed, though.
computeStyleTests();
return pixelPositionVal;
},
boxSizingReliable: function() {
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
+ computeStyleTests();
return boxSizingReliableVal;
},
pixelMarginRight: function() {
-
- // Support: Android 4.0-4.3
- // We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
- // since that compresses better and they're computed together anyway.
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
+ computeStyleTests();
return pixelMarginRightVal;
},
reliableMarginLeft: function() {
-
- // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
+ computeStyleTests();
return reliableMarginLeftVal;
}
} );
diff --git a/src/css/var/cssExpand.js b/src/css/var/cssExpand.js
index 9f8194d..dd2007c 100644
--- a/src/css/var/cssExpand.js
+++ b/src/css/var/cssExpand.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return [ "Top", "Right", "Bottom", "Left" ];
} );
diff --git a/src/css/var/getStyles.js b/src/css/var/getStyles.js
index 1fa915d..0b893ac 100644
--- a/src/css/var/getStyles.js
+++ b/src/css/var/getStyles.js
@@ -1,12 +1,14 @@
define( function() {
+ "use strict";
+
return function( elem ) {
- // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+ // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
// IE throws on elements created in popups
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
var view = elem.ownerDocument.defaultView;
- if ( !view.opener ) {
+ if ( !view || !view.opener ) {
view = window;
}
diff --git a/src/css/var/isHidden.js b/src/css/var/isHidden.js
deleted file mode 100644
index 7997eff..0000000
--- a/src/css/var/isHidden.js
+++ /dev/null
@@ -1,16 +0,0 @@
-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 );
- };
-} );
diff --git a/src/css/var/isHiddenWithinTree.js b/src/css/var/isHiddenWithinTree.js
new file mode 100644
index 0000000..3cfb93e
--- /dev/null
+++ b/src/css/var/isHiddenWithinTree.js
@@ -0,0 +1,34 @@
+define( [
+ "../../core",
+ "../../selector"
+
+ // css is assumed
+], function( jQuery ) {
+ "use strict";
+
+ // isHiddenWithinTree reports if an element has a non-"none" display style (inline and/or
+ // through the CSS cascade), which is useful in deciding whether or not to make it visible.
+ // It differs from the :hidden selector (jQuery.expr.pseudos.hidden) in two important ways:
+ // * A hidden ancestor does not force an element to be classified as hidden.
+ // * Being disconnected from the document does not force an element to be classified as hidden.
+ // These differences improve the behavior of .toggle() et al. when applied to elements that are
+ // detached or contained within hidden ancestors (gh-2404, gh-2863).
+ return function( elem, el ) {
+
+ // isHiddenWithinTree might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+
+ // Inline style trumps all
+ return elem.style.display === "none" ||
+ elem.style.display === "" &&
+
+ // Otherwise, check computed style
+ // Support: Firefox <=43 - 45
+ // Disconnected elements can have computed display: none, so first confirm that elem is
+ // in the document.
+ jQuery.contains( elem.ownerDocument, elem ) &&
+
+ jQuery.css( elem, "display" ) === "none";
+ };
+} );
diff --git a/src/css/var/rmargin.js b/src/css/var/rmargin.js
index 9be2212..0fbfbd8 100644
--- a/src/css/var/rmargin.js
+++ b/src/css/var/rmargin.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /^margin/ );
} );
diff --git a/src/css/var/rnumnonpx.js b/src/css/var/rnumnonpx.js
index ed13f0b..056cda7 100644
--- a/src/css/var/rnumnonpx.js
+++ b/src/css/var/rnumnonpx.js
@@ -1,5 +1,7 @@
define( [
"../../var/pnum"
], function( pnum ) {
+ "use strict";
+
return new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
} );
diff --git a/src/css/var/swap.js b/src/css/var/swap.js
index b6d3b67..1a9556b 100644
--- a/src/css/var/swap.js
+++ b/src/css/var/swap.js
@@ -1,5 +1,7 @@
define( function() {
+"use strict";
+
// A method for quickly swapping in/out CSS properties to get correct calculations.
return function( elem, options, callback, args ) {
var ret, name,
diff --git a/src/data.js b/src/data.js
index d2855dd..087ce4e 100644
--- a/src/data.js
+++ b/src/data.js
@@ -5,6 +5,8 @@ define( [
"./data/var/dataUser"
], function( jQuery, access, dataPriv, dataUser ) {
+"use strict";
+
// Implementation Summary
//
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
@@ -18,6 +20,31 @@ define( [
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
rmultiDash = /[A-Z]/g;
+function getData( data ) {
+ if ( data === "true" ) {
+ return true;
+ }
+
+ if ( data === "false" ) {
+ return false;
+ }
+
+ if ( data === "null" ) {
+ return null;
+ }
+
+ // Only convert to a number if it doesn't change the string
+ if ( data === +data + "" ) {
+ return +data;
+ }
+
+ if ( rbrace.test( data ) ) {
+ return JSON.parse( data );
+ }
+
+ return data;
+}
+
function dataAttr( elem, key, data ) {
var name;
@@ -29,14 +56,7 @@ function dataAttr( elem, key, data ) {
if ( typeof data === "string" ) {
try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
-
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
+ data = getData( data );
} catch ( e ) {}
// Make sure we set the data so it isn't changed later
@@ -87,7 +107,7 @@ jQuery.fn.extend( {
i = attrs.length;
while ( i-- ) {
- // Support: IE11+
+ // Support: IE 11 only
// The attrs elements can be null (#14894)
if ( attrs[ i ] ) {
name = attrs[ i ].name;
diff --git a/src/data/Data.js b/src/data/Data.js
index e214282..43ae016 100644
--- a/src/data/Data.js
+++ b/src/data/Data.js
@@ -1,8 +1,10 @@
define( [
"../core",
- "../var/rnotwhite",
+ "../var/rnothtmlwhite",
"./var/acceptData"
-], function( jQuery, rnotwhite, acceptData ) {
+], function( jQuery, rnothtmlwhite, acceptData ) {
+
+"use strict";
function Data() {
this.expando = jQuery.expando + Data.uid++;
@@ -125,7 +127,7 @@ Data.prototype = {
// Otherwise, create an array by matching non-whitespace
key = key in cache ?
[ key ] :
- ( key.match( rnotwhite ) || [] );
+ ( key.match( rnothtmlwhite ) || [] );
}
i = key.length;
@@ -138,10 +140,10 @@ Data.prototype = {
// Remove the expando if there's no more data
if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
- // Support: Chrome <= 35-45+
+ // Support: Chrome <=35 - 45
// Webkit & Blink performance suffers when deleting properties
// from DOM nodes, so set to undefined instead
- // https://code.google.com/p/chromium/issues/detail?id=378607
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
if ( owner.nodeType ) {
owner[ this.expando ] = undefined;
} else {
diff --git a/src/data/var/acceptData.js b/src/data/var/acceptData.js
index 6e15af1..e00f753 100644
--- a/src/data/var/acceptData.js
+++ b/src/data/var/acceptData.js
@@ -1,5 +1,7 @@
define( function() {
+"use strict";
+
/**
* Determines whether an object can have data
*/
@@ -11,7 +13,6 @@ return function( owner ) {
// - Node.DOCUMENT_NODE
// - Object
// - Any
- /* jshint -W018 */
return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
};
diff --git a/src/data/var/dataPriv.js b/src/data/var/dataPriv.js
index 9a1343c..72713c8 100644
--- a/src/data/var/dataPriv.js
+++ b/src/data/var/dataPriv.js
@@ -1,5 +1,7 @@
define( [
"../Data"
], function( Data ) {
+ "use strict";
+
return new Data();
} );
diff --git a/src/data/var/dataUser.js b/src/data/var/dataUser.js
index 9a1343c..72713c8 100644
--- a/src/data/var/dataUser.js
+++ b/src/data/var/dataUser.js
@@ -1,5 +1,7 @@
define( [
"../Data"
], function( Data ) {
+ "use strict";
+
return new Data();
} );
diff --git a/src/deferred.js b/src/deferred.js
index bc2ea86..8139515 100644
--- a/src/deferred.js
+++ b/src/deferred.js
@@ -4,6 +4,8 @@ define( [
"./callbacks"
], function( jQuery, slice ) {
+"use strict";
+
function Identity( v ) {
return v;
}
@@ -11,6 +13,38 @@ function Thrower( ex ) {
throw ex;
}
+function adoptValue( value, resolve, reject ) {
+ var method;
+
+ try {
+
+ // Check for promise aspect first to privilege synchronous behavior
+ if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
+ method.call( value ).done( resolve ).fail( reject );
+
+ // Other thenables
+ } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
+ method.call( value, resolve, reject );
+
+ // Other non-thenables
+ } else {
+
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ resolve.call( undefined, value );
+ }
+
+ // For Promises/A+, convert exceptions into rejections
+ // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+ // Deferred#then to conditionally suppress rejection.
+ } catch ( value ) {
+
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ reject.call( undefined, value );
+ }
+}
+
jQuery.extend( {
Deferred: function( func ) {
@@ -60,7 +94,7 @@ jQuery.extend( {
.fail( newDefer.reject );
} else {
newDefer[ tuple[ 0 ] + "With" ](
- this === promise ? newDefer.promise() : this,
+ this,
fn ? [ returned ] : arguments
);
}
@@ -73,7 +107,7 @@ jQuery.extend( {
var maxDepth = 0;
function resolve( depth, deferred, handler, special ) {
return function() {
- var that = this === promise ? undefined : this,
+ var that = this,
args = arguments,
mightThrow = function() {
var returned, then;
@@ -128,7 +162,7 @@ jQuery.extend( {
resolve( maxDepth, deferred, Identity, special ),
resolve( maxDepth, deferred, Thrower, special ),
resolve( maxDepth, deferred, Identity,
- deferred.notify )
+ deferred.notifyWith )
);
}
@@ -144,8 +178,7 @@ jQuery.extend( {
// Process the value(s)
// Default process is resolve
- ( special || deferred.resolveWith )(
- that || deferred.promise(), args );
+ ( special || deferred.resolveWith )( that, args );
}
},
@@ -174,8 +207,7 @@ jQuery.extend( {
args = [ e ];
}
- deferred.rejectWith( that || deferred.promise(),
- args );
+ deferred.rejectWith( that, args );
}
}
};
@@ -282,7 +314,7 @@ jQuery.extend( {
// deferred.resolve = function() { deferred.resolveWith(...) }
// deferred.reject = function() { deferred.rejectWith(...) }
deferred[ tuple[ 0 ] ] = function() {
- deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
return this;
};
@@ -305,62 +337,48 @@ jQuery.extend( {
},
// Deferred helper
- when: function() {
- var method, resolveContexts,
- i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
+ when: function( singleValue ) {
+ var
+
+ // count of uncompleted subordinates
+ remaining = arguments.length,
- // the count of uncompleted subordinates
- remaining = length,
+ // count of unprocessed arguments
+ i = remaining,
- // the master Deferred.
+ // subordinate fulfillment data
+ resolveContexts = Array( i ),
+ resolveValues = slice.call( arguments ),
+
+ // the master Deferred
master = jQuery.Deferred(),
- // Update function for both resolving subordinates
+ // subordinate callback factory
updateFunc = function( i ) {
return function( value ) {
resolveContexts[ i ] = this;
resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
if ( !( --remaining ) ) {
- master.resolveWith(
- resolveContexts.length === 1 ? resolveContexts[ 0 ] : resolveContexts,
- resolveValues
- );
+ master.resolveWith( resolveContexts, resolveValues );
}
};
};
- // Add listeners to promise-like subordinates; treat others as resolved
- if ( length > 0 ) {
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
-
- // jQuery.Deferred - treated specially to get resolve-sync behavior
- if ( resolveValues[ i ] &&
- jQuery.isFunction( ( method = resolveValues[ i ].promise ) ) ) {
-
- method.call( resolveValues[ i ] )
- .done( updateFunc( i ) )
- .fail( master.reject );
-
- // Other thenables
- } else if ( resolveValues[ i ] &&
- jQuery.isFunction( ( method = resolveValues[ i ].then ) ) ) {
-
- method.call(
- resolveValues[ i ],
- updateFunc( i ),
- master.reject
- );
- } else {
- updateFunc( i )( resolveValues[ i ] );
- }
+ // Single- and empty arguments are adopted like Promise.resolve
+ if ( remaining <= 1 ) {
+ adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );
+
+ // Use .then() to unwrap secondary thenables (cf. gh-3000)
+ if ( master.state() === "pending" ||
+ jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+ return master.then();
}
+ }
- // If we're not waiting on anything, resolve the master
- } else {
- master.resolveWith();
+ // Multiple arguments are aggregated like Promise.all array elements
+ while ( i-- ) {
+ adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
}
return master.promise();
diff --git a/src/deferred/exceptionHook.js b/src/deferred/exceptionHook.js
index b995506..6dbdc85 100644
--- a/src/deferred/exceptionHook.js
+++ b/src/deferred/exceptionHook.js
@@ -3,16 +3,18 @@ define( [
"../deferred"
], function( jQuery ) {
+"use strict";
+
// These usually indicate a programmer mistake during development,
// warn about them ASAP rather than swallowing them by default.
var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
jQuery.Deferred.exceptionHook = function( error, stack ) {
- // Support: IE9
+ // Support: IE 8 - 9 only
// Console exists when dev tools are open, which can happen at any time
if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
- window.console.warn( "jQuery.Deferred exception: " + error.message, stack );
+ window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
}
};
diff --git a/src/deprecated.js b/src/deprecated.js
index 7888526..9fcc6b7 100644
--- a/src/deprecated.js
+++ b/src/deprecated.js
@@ -2,6 +2,8 @@ define( [
"./core"
], function( jQuery ) {
+"use strict";
+
jQuery.fn.extend( {
bind: function( types, data, fn ) {
@@ -23,4 +25,6 @@ jQuery.fn.extend( {
}
} );
+jQuery.parseJSON = JSON.parse;
+
} );
diff --git a/src/dimensions.js b/src/dimensions.js
index 3d4dbff..46e7b1c 100644
--- a/src/dimensions.js
+++ b/src/dimensions.js
@@ -4,6 +4,8 @@ define( [
"./css"
], function( jQuery, access ) {
+"use strict";
+
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
diff --git a/src/effects.js b/src/effects.js
index 43162e1..68af96c 100644
--- a/src/effects.js
+++ b/src/effects.js
@@ -2,9 +2,9 @@ define( [
"./core",
"./var/document",
"./var/rcssNum",
- "./var/rnotwhite",
+ "./var/rnothtmlwhite",
"./css/var/cssExpand",
- "./css/var/isHidden",
+ "./css/var/isHiddenWithinTree",
"./css/var/swap",
"./css/adjustCSS",
"./data/var/dataPriv",
@@ -17,9 +17,11 @@ define( [
"./manipulation",
"./css",
"./effects/Tween"
-], function( jQuery, document, rcssNum, rnotwhite, cssExpand, isHidden, swap,
+], function( jQuery, document, rcssNum, rnothtmlwhite, cssExpand, isHiddenWithinTree, swap,
adjustCSS, dataPriv, showHide ) {
+"use strict";
+
var
fxNow, timerId,
rfxtypes = /^(?:toggle|show|hide)$/,
@@ -49,7 +51,7 @@ function genFx( type, includeWidth ) {
// If we include width, step value is 1 to do all cssExpand values,
// otherwise step value is 2 to skip over Left and Right
includeWidth = includeWidth ? 1 : 0;
- for ( ; i < 4 ; i += 2 - includeWidth ) {
+ for ( ; i < 4; i += 2 - includeWidth ) {
which = cssExpand[ i ];
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
}
@@ -76,13 +78,12 @@ function createTween( value, prop, animation ) {
}
function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
isBox = "width" in props || "height" in props,
anim = this,
orig = {},
style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
+ hidden = elem.nodeType && isHiddenWithinTree( elem ),
dataShow = dataPriv.get( elem, "fxshow" );
// Queue-skipping animations hijack the fx hooks
@@ -142,7 +143,7 @@ function defaultPrefilter( elem, props, opts ) {
// Restrict "overflow" and "display" styles during box animations
if ( isBox && elem.nodeType === 1 ) {
- // Support: IE 9 - 11
+ // Support: IE <=9 - 11, Edge 12 - 13
// Record all 3 overflow attributes because IE does not infer the shorthand
// from identically-valued overflowX and overflowY
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
@@ -218,9 +219,12 @@ function defaultPrefilter( elem, props, opts ) {
showHide( [ elem ], true );
}
- /* jshint -W083 */
+ /* eslint-disable no-loop-func */
+
anim.done( function() {
+ /* eslint-enable no-loop-func */
+
// The final step of a "hide" animation is actually hiding the element
if ( !hidden ) {
showHide( [ elem ] );
@@ -238,7 +242,7 @@ function defaultPrefilter( elem, props, opts ) {
dataShow[ prop ] = propTween.start;
if ( hidden ) {
propTween.end = propTween.start;
- propTween.start = prop === "width" || prop === "height" ? 1 : 0;
+ propTween.start = 0;
}
}
}
@@ -298,14 +302,14 @@ function Animation( elem, properties, options ) {
var currentTime = fxNow || createFxNow(),
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
- // Support: Android 2.3
+ // Support: Android 2.3 only
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
temp = remaining / animation.duration || 0,
percent = 1 - temp,
index = 0,
length = animation.tweens.length;
- for ( ; index < length ; index++ ) {
+ for ( ; index < length; index++ ) {
animation.tweens[ index ].run( percent );
}
@@ -346,7 +350,7 @@ function Animation( elem, properties, options ) {
return this;
}
stopped = true;
- for ( ; index < length ; index++ ) {
+ for ( ; index < length; index++ ) {
animation.tweens[ index ].run( 1 );
}
@@ -364,7 +368,7 @@ function Animation( elem, properties, options ) {
propFilter( props, animation.opts.specialEasing );
- for ( ; index < length ; index++ ) {
+ for ( ; index < length; index++ ) {
result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
if ( result ) {
if ( jQuery.isFunction( result.stop ) ) {
@@ -411,14 +415,14 @@ jQuery.Animation = jQuery.extend( Animation, {
callback = props;
props = [ "*" ];
} else {
- props = props.match( rnotwhite );
+ props = props.match( rnothtmlwhite );
}
var prop,
index = 0,
length = props.length;
- for ( ; index < length ; index++ ) {
+ for ( ; index < length; index++ ) {
prop = props[ index ];
Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
Animation.tweeners[ prop ].unshift( callback );
@@ -449,9 +453,14 @@ jQuery.speed = function( speed, easing, fn ) {
opt.duration = 0;
} else {
- opt.duration = typeof opt.duration === "number" ?
- opt.duration : opt.duration in jQuery.fx.speeds ?
- jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+ if ( typeof opt.duration !== "number" ) {
+ if ( opt.duration in jQuery.fx.speeds ) {
+ opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+ } else {
+ opt.duration = jQuery.fx.speeds._default;
+ }
+ }
}
// Normalize opt.queue - true/undefined/null -> "fx"
@@ -479,7 +488,7 @@ jQuery.fn.extend( {
fadeTo: function( speed, to, easing, callback ) {
// Show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
+ return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
// Animate to the value specified
.end().animate( { opacity: to }, speed, easing, callback );
diff --git a/src/effects/Tween.js b/src/effects/Tween.js
index 47f15a9..43eb8fa 100644
--- a/src/effects/Tween.js
+++ b/src/effects/Tween.js
@@ -3,6 +3,8 @@ define( [
"../css"
], function( jQuery ) {
+"use strict";
+
function Tween( elem, options, prop, end, easing ) {
return new Tween.prototype.init( elem, options, prop, end, easing );
}
@@ -27,12 +29,17 @@ Tween.prototype = {
Tween.propHooks._default.get( this );
},
run: function( percent ) {
- var hooks = Tween.propHooks[ this.prop ];
+ var eased,
+ hooks = Tween.propHooks[ this.prop ];
- this.pos = this.options.duration ?
- jQuery.easing[ this.easing ]( percent ) :
- percent;
- this.now = ( this.end - this.start ) * this.pos + this.start;
+ 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 );
@@ -88,7 +95,7 @@ Tween.propHooks = {
}
};
-// Support: IE9
+// Support: IE <=9 only
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) {
@@ -110,7 +117,7 @@ jQuery.easing = {
jQuery.fx = Tween.prototype.init;
-// Back Compat <1.8 extension point
+// Back compat <1.8 extension point
jQuery.fx.step = {};
} );
diff --git a/src/effects/animatedSelector.js b/src/effects/animatedSelector.js
index d84c9c7..24c1bfb 100644
--- a/src/effects/animatedSelector.js
+++ b/src/effects/animatedSelector.js
@@ -4,7 +4,9 @@ define( [
"../effects"
], function( jQuery ) {
-jQuery.expr.filters.animated = function( elem ) {
+"use strict";
+
+jQuery.expr.pseudos.animated = function( elem ) {
return jQuery.grep( jQuery.timers, function( fn ) {
return elem === fn.elem;
} ).length;
diff --git a/src/event.js b/src/event.js
index ddd92c5..ab2c63c 100644
--- a/src/event.js
+++ b/src/event.js
@@ -1,13 +1,16 @@
define( [
"./core",
"./var/document",
- "./var/rnotwhite",
+ "./var/documentElement",
+ "./var/rnothtmlwhite",
"./var/slice",
"./data/var/dataPriv",
"./core/init",
"./selector"
-], function( jQuery, document, rnotwhite, slice, dataPriv ) {
+], function( jQuery, document, documentElement, rnothtmlwhite, slice, dataPriv ) {
+
+"use strict";
var
rkeyEvent = /^key/,
@@ -22,7 +25,7 @@ function returnFalse() {
return false;
}
-// Support: IE9
+// Support: IE <=9 only
// See #13393 for more info
function safeActiveElement() {
try {
@@ -70,6 +73,8 @@ function on( elem, types, selector, data, fn, one ) {
}
if ( fn === false ) {
fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
}
if ( one === 1 ) {
@@ -116,6 +121,12 @@ jQuery.event = {
selector = handleObjIn.selector;
}
+ // Ensure that invalid selectors throw exceptions at attach time
+ // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+ if ( selector ) {
+ jQuery.find.matchesSelector( documentElement, selector );
+ }
+
// Make sure that the handler has a unique ID, used to find/remove it later
if ( !handler.guid ) {
handler.guid = jQuery.guid++;
@@ -136,7 +147,7 @@ jQuery.event = {
}
// Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[ t ] ) || [];
@@ -218,7 +229,7 @@ jQuery.event = {
}
// Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[ t ] ) || [];
@@ -279,19 +290,23 @@ jQuery.event = {
}
},
- dispatch: function( event ) {
+ dispatch: function( nativeEvent ) {
// Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
+ var event = jQuery.event.fix( nativeEvent );
- var i, j, ret, matched, handleObj,
- handlerQueue = [],
- args = slice.call( arguments ),
+ var i, j, ret, matched, handleObj, handlerQueue,
+ args = new Array( arguments.length ),
handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
args[ 0 ] = event;
+
+ for ( i = 1; i < arguments.length; i++ ) {
+ args[ i ] = arguments[ i ];
+ }
+
event.delegateTarget = this;
// Call the preDispatch hook for the mapped type, and let it bail if desired
@@ -340,140 +355,95 @@ jQuery.event = {
},
handlers: function( event, handlers ) {
- var i, matches, sel, handleObj,
+ var i, handleObj, sel, matchedHandlers, matchedSelectors,
handlerQueue = [],
delegateCount = handlers.delegateCount,
cur = event.target;
- // Support (at least): Chrome, IE9
// Find delegate handlers
- // Black-hole SVG <use> instance trees (#13180)
- //
- // Support: Firefox<=42+
- // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
- if ( delegateCount && cur.nodeType &&
- ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
+ if ( delegateCount &&
+
+ // Support: IE <=9
+ // Black-hole SVG <use> instance trees (trac-13180)
+ cur.nodeType &&
+
+ // Support: Firefox <=42
+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+ // Support: IE 11 only
+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+ !( event.type === "click" && event.button >= 1 ) ) {
for ( ; cur !== this; cur = cur.parentNode || this ) {
// Don't check non-elements (#13208)
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
- matches = [];
+ if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+ matchedHandlers = [];
+ matchedSelectors = {};
for ( i = 0; i < delegateCount; i++ ) {
handleObj = handlers[ i ];
// Don't conflict with Object.prototype properties (#13203)
sel = handleObj.selector + " ";
- if ( matches[ sel ] === undefined ) {
- matches[ sel ] = handleObj.needsContext ?
+ if ( matchedSelectors[ sel ] === undefined ) {
+ matchedSelectors[ sel ] = handleObj.needsContext ?
jQuery( sel, this ).index( cur ) > -1 :
jQuery.find( sel, this, null, [ cur ] ).length;
}
- if ( matches[ sel ] ) {
- matches.push( handleObj );
+ if ( matchedSelectors[ sel ] ) {
+ matchedHandlers.push( handleObj );
}
}
- if ( matches.length ) {
- handlerQueue.push( { elem: cur, handlers: matches } );
+ if ( matchedHandlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
}
}
}
}
// Add the remaining (directly-bound) handlers
+ cur = this;
if ( delegateCount < handlers.length ) {
- handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
+ handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
}
return handlerQueue;
},
- // Includes some event props shared by KeyEvent and MouseEvent
- props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
- "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split( " " ),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
- "screenX screenY toElement" ).split( " " ),
- filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX +
- ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
- ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY +
- ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
- ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
+ addProp: function( name, hook ) {
+ Object.defineProperty( jQuery.Event.prototype, name, {
+ enumerable: true,
+ configurable: true,
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+ get: jQuery.isFunction( hook ) ?
+ function() {
+ if ( this.originalEvent ) {
+ return hook( this.originalEvent );
+ }
+ } :
+ function() {
+ if ( this.originalEvent ) {
+ return this.originalEvent[ name ];
+ }
+ },
+
+ set: function( value ) {
+ Object.defineProperty( this, name, {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: value
+ } );
}
-
- return event;
- }
+ } );
},
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: Safari 6-8+
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+ fix: function( originalEvent ) {
+ return originalEvent[ jQuery.expando ] ?
+ originalEvent :
+ new jQuery.Event( originalEvent );
},
special: {
@@ -556,11 +526,21 @@ jQuery.Event = function( src, props ) {
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
- // Support: Android<4.0
+ // Support: Android <=2.3 only
src.returnValue === false ?
returnTrue :
returnFalse;
+ // Create target properties
+ // Support: Safari <=6 - 7 only
+ // Target should not be a text node (#504, #13143)
+ this.target = ( src.target && src.target.nodeType === 3 ) ?
+ src.target.parentNode :
+ src.target;
+
+ this.currentTarget = src.currentTarget;
+ this.relatedTarget = src.relatedTarget;
+
// Event type
} else {
this.type = src;
@@ -579,19 +559,20 @@ jQuery.Event = function( src, props ) {
};
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
constructor: jQuery.Event,
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
preventDefault: function() {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
- if ( e ) {
+ if ( e && !this.isSimulated ) {
e.preventDefault();
}
},
@@ -600,7 +581,7 @@ jQuery.Event.prototype = {
this.isPropagationStopped = returnTrue;
- if ( e ) {
+ if ( e && !this.isSimulated ) {
e.stopPropagation();
}
},
@@ -609,7 +590,7 @@ jQuery.Event.prototype = {
this.isImmediatePropagationStopped = returnTrue;
- if ( e ) {
+ if ( e && !this.isSimulated ) {
e.stopImmediatePropagation();
}
@@ -617,13 +598,74 @@ jQuery.Event.prototype = {
}
};
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+ altKey: true,
+ bubbles: true,
+ cancelable: true,
+ changedTouches: true,
+ ctrlKey: true,
+ detail: true,
+ eventPhase: true,
+ metaKey: true,
+ pageX: true,
+ pageY: true,
+ shiftKey: true,
+ view: true,
+ "char": true,
+ charCode: true,
+ key: true,
+ keyCode: true,
+ button: true,
+ buttons: true,
+ clientX: true,
+ clientY: true,
+ offsetX: true,
+ offsetY: true,
+ pointerId: true,
+ pointerType: true,
+ screenX: true,
+ screenY: true,
+ targetTouches: true,
+ toElement: true,
+ touches: true,
+
+ which: function( event ) {
+ var button = event.button;
+
+ // Add which for key events
+ if ( event.which == null && rkeyEvent.test( event.type ) ) {
+ return event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+ if ( button & 1 ) {
+ return 1;
+ }
+
+ if ( button & 2 ) {
+ return 3;
+ }
+
+ if ( button & 4 ) {
+ return 2;
+ }
+
+ return 0;
+ }
+
+ return event.which;
+ }
+}, jQuery.event.addProp );
+
// Create mouseenter/leave events using mouseover/out and event-time checks
// so that event delegation works in jQuery.
// Do the same for pointerenter/pointerleave and pointerover/pointerout
//
// Support: Safari 7 only
// Safari sends mouseenter too often; see:
-// https://code.google.com/p/chromium/issues/detail?id=470258
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
// for the description of the bug (it existed in older Chrome versions as well).
jQuery.each( {
mouseenter: "mouseover",
diff --git a/src/event/ajax.js b/src/event/ajax.js
index 98e194b..500b36c 100644
--- a/src/event/ajax.js
+++ b/src/event/ajax.js
@@ -3,6 +3,8 @@ define( [
"../event"
], function( jQuery ) {
+"use strict";
+
// Attach a bunch of functions for handling common AJAX events
jQuery.each( [
"ajaxStart",
diff --git a/src/event/alias.js b/src/event/alias.js
index b1b8f70..863c94a 100644
--- a/src/event/alias.js
+++ b/src/event/alias.js
@@ -5,6 +5,8 @@ define( [
"./trigger"
], function( jQuery ) {
+"use strict";
+
jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup contextmenu" ).split( " " ),
diff --git a/src/event/focusin.js b/src/event/focusin.js
index ae7f831..7faef29 100644
--- a/src/event/focusin.js
+++ b/src/event/focusin.js
@@ -7,14 +7,16 @@ define( [
"./trigger"
], function( jQuery, dataPriv, support ) {
-// Support: Firefox
+"use strict";
+
+// Support: Firefox <=44
// Firefox doesn't have focus(in | out) events
// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
//
-// Support: Chrome, Safari
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
// focus(in | out) events fire after focus & blur events,
// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
-// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
if ( !support.focusin ) {
jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
diff --git a/src/event/support.js b/src/event/support.js
index 1c4d416..e3db9ad 100644
--- a/src/event/support.js
+++ b/src/event/support.js
@@ -2,6 +2,8 @@ define( [
"../var/support"
], function( support ) {
+"use strict";
+
support.focusin = "onfocusin" in window;
return support;
diff --git a/src/event/trigger.js b/src/event/trigger.js
index 8f5f778..ef39137 100644
--- a/src/event/trigger.js
+++ b/src/event/trigger.js
@@ -8,6 +8,8 @@ define( [
"../event"
], function( jQuery, document, dataPriv, acceptData, hasOwn ) {
+"use strict";
+
var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
jQuery.extend( jQuery.event, {
@@ -148,6 +150,7 @@ jQuery.extend( jQuery.event, {
},
// Piggyback on a donor event to simulate a different one
+ // Used only for `focus(in | out)` events
simulate: function( type, elem, event ) {
var e = jQuery.extend(
new jQuery.Event(),
@@ -155,27 +158,10 @@ jQuery.extend( jQuery.event, {
{
type: type,
isSimulated: true
-
- // Previously, `originalEvent: {}` was set here, so stopPropagation call
- // would not be triggered on donor event, since in our own
- // jQuery.event.stopPropagation function we had a check for existence of
- // originalEvent.stopPropagation method, so, consequently it would be a noop.
- //
- // But now, this "simulate" function is used only for events
- // for which stopPropagation() is noop, so there is no need for that anymore.
- //
- // For the compat branch though, guard for "click" and "submit"
- // events is still used, but was moved to jQuery.event.stopPropagation function
- // because `originalEvent` should point to the original event for the constancy
- // with other events and for more focused logic
}
);
jQuery.event.trigger( e, null, elem );
-
- if ( e.isDefaultPrevented() ) {
- event.preventDefault();
- }
}
} );
diff --git a/src/exports/amd.js b/src/exports/amd.js
index add6eb9..cbb1ef5 100644
--- a/src/exports/amd.js
+++ b/src/exports/amd.js
@@ -2,6 +2,8 @@ define( [
"../core"
], function( jQuery ) {
+"use strict";
+
// 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
diff --git a/src/exports/global.js b/src/exports/global.js
index be9cbfb..460b56e 100644
--- a/src/exports/global.js
+++ b/src/exports/global.js
@@ -1,3 +1,9 @@
+define( [
+ "../core"
+], function( jQuery, noGlobal ) {
+
+"use strict";
+
var
// Map over jQuery in case of overwrite
@@ -24,3 +30,5 @@ jQuery.noConflict = function( deep ) {
if ( !noGlobal ) {
window.jQuery = window.$ = jQuery;
}
+
+} );
diff --git a/src/jquery.js b/src/jquery.js
index 4cc9c8a..52fc87d 100644
--- a/src/jquery.js
+++ b/src/jquery.js
@@ -30,9 +30,12 @@ define( [
"./offset",
"./dimensions",
"./deprecated",
- "./exports/amd"
+ "./exports/amd",
+ "./exports/global"
], function( jQuery ) {
-return ( window.jQuery = window.$ = jQuery );
+"use strict";
+
+return jQuery;
} );
diff --git a/src/manipulation.js b/src/manipulation.js
index 0d10219..9b4f5e4 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -26,10 +26,18 @@ define( [
wrapMap, getAll, setGlobalEval, buildFragment, support,
dataPriv, dataUser, acceptData, DOMEval ) {
+"use strict";
+
var
+
+ /* eslint-disable max-len */
+
+ // See https://github.com/eslint/eslint/issues/3229
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
- // Support: IE 10-11, Edge 10240+
+ /* eslint-enable */
+
+ // Support: IE <=10 - 11, Edge 12 - 13
// In IE/Edge using regex groups here causes severe slowdowns.
// See https://connect.microsoft.com/IE/feedback/details/1736512/
rnoInnerhtml = /<script|<style|<link/i,
@@ -164,7 +172,7 @@ function domManip( collection, args, callback, ignored ) {
// Keep references to cloned scripts for later restoration
if ( hasScripts ) {
- // Support: Android<4.1, PhantomJS<2
+ // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( scripts, getAll( node, "script" ) );
}
@@ -292,13 +300,13 @@ jQuery.extend( {
}
}
- // Support: Chrome <= 35-45+
+ // Support: Chrome <=35 - 45+
// Assign undefined instead of using delete, see Data#remove
elem[ dataPriv.expando ] = undefined;
}
if ( elem[ dataUser.expando ] ) {
- // Support: Chrome <= 35-45+
+ // Support: Chrome <=35 - 45+
// Assign undefined instead of using delete, see Data#remove
elem[ dataUser.expando ] = undefined;
}
@@ -465,7 +473,7 @@ jQuery.each( {
elems = i === last ? this : this.clone( true );
jQuery( insert[ i ] )[ original ]( elems );
- // Support: Android<4.1, PhantomJS<2
+ // Support: Android <=4.0 only, PhantomJS 1 only
// .get() because push.apply(_, arraylike) throws on ancient WebKit
push.apply( ret, elems.get() );
}
diff --git a/src/manipulation/_evalUrl.js b/src/manipulation/_evalUrl.js
index 572fe30..f9ec702 100644
--- a/src/manipulation/_evalUrl.js
+++ b/src/manipulation/_evalUrl.js
@@ -2,6 +2,8 @@ define( [
"../ajax"
], function( jQuery ) {
+"use strict";
+
jQuery._evalUrl = function( url ) {
return jQuery.ajax( {
url: url,
diff --git a/src/manipulation/buildFragment.js b/src/manipulation/buildFragment.js
index cfdd1c0..bcb5085 100644
--- a/src/manipulation/buildFragment.js
+++ b/src/manipulation/buildFragment.js
@@ -7,6 +7,8 @@ define( [
"./setGlobalEval"
], function( jQuery, rtagName, rscriptType, wrapMap, getAll, setGlobalEval ) {
+"use strict";
+
var rhtml = /<|&#?\w+;/;
function buildFragment( elems, context, scripts, selection, ignored ) {
@@ -24,7 +26,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
// Add nodes directly
if ( jQuery.type( elem ) === "object" ) {
- // Support: Android<4.1, PhantomJS<2
+ // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
@@ -47,7 +49,7 @@ function buildFragment( elems, context, scripts, selection, ignored ) {
tmp = tmp.lastChild;
}
- // Support: Android<4.1, PhantomJS<2
+ // Support: Android <=4.0 only, PhantomJS 1 only
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, tmp.childNodes );
diff --git a/src/manipulation/getAll.js b/src/manipulation/getAll.js
index cc913f2..f68e321 100644
--- a/src/manipulation/getAll.js
+++ b/src/manipulation/getAll.js
@@ -2,19 +2,29 @@ define( [
"../core"
], function( jQuery ) {
+"use strict";
+
function getAll( context, tag ) {
- // Support: IE9-11+
+ // Support: IE <=9 - 11 only
// Use typeof to avoid zero-argument method invocation on host objects (#15151)
- var ret = typeof context.getElementsByTagName !== "undefined" ?
- context.getElementsByTagName( tag || "*" ) :
- typeof context.querySelectorAll !== "undefined" ?
- context.querySelectorAll( tag || "*" ) :
- [];
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], ret ) :
- ret;
+ var ret;
+
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ ret = context.getElementsByTagName( tag || "*" );
+
+ } else if ( typeof context.querySelectorAll !== "undefined" ) {
+ ret = context.querySelectorAll( tag || "*" );
+
+ } else {
+ ret = [];
+ }
+
+ if ( tag === undefined || tag && jQuery.nodeName( context, tag ) ) {
+ return jQuery.merge( [ context ], ret );
+ }
+
+ return ret;
}
return getAll;
diff --git a/src/manipulation/setGlobalEval.js b/src/manipulation/setGlobalEval.js
index 8ca69a0..cf95240 100644
--- a/src/manipulation/setGlobalEval.js
+++ b/src/manipulation/setGlobalEval.js
@@ -2,6 +2,8 @@ define( [
"../data/var/dataPriv"
], function( dataPriv ) {
+"use strict";
+
// Mark scripts as having already been evaluated
function setGlobalEval( elems, refElements ) {
var i = 0,
diff --git a/src/manipulation/support.js b/src/manipulation/support.js
index 4f6b9de..4a5d9af 100644
--- a/src/manipulation/support.js
+++ b/src/manipulation/support.js
@@ -3,12 +3,14 @@ define( [
"../var/support"
], function( document, support ) {
+"use strict";
+
( function() {
var fragment = document.createDocumentFragment(),
div = fragment.appendChild( document.createElement( "div" ) ),
input = document.createElement( "input" );
- // Support: Android 4.0-4.3
+ // Support: Android 4.0 - 4.3 only
// Check state lost if the name is set (#11217)
// Support: Windows Web Apps (WWA)
// `name` and `type` must use .setAttribute for WWA (#14901)
@@ -18,11 +20,11 @@ define( [
div.appendChild( input );
- // Support: Android<4.2
+ // Support: Android <=4.1 only
// Older WebKit doesn't clone checked state correctly in fragments
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
- // Support: IE<=11+
+ // Support: IE <=11 only
// Make sure textarea (and checkbox) defaultValue is properly cloned
div.innerHTML = "<textarea>x</textarea>";
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
diff --git a/src/manipulation/var/rcheckableType.js b/src/manipulation/var/rcheckableType.js
index 4c95394..25bbcb4 100644
--- a/src/manipulation/var/rcheckableType.js
+++ b/src/manipulation/var/rcheckableType.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /^(?:checkbox|radio)$/i );
} );
diff --git a/src/manipulation/var/rscriptType.js b/src/manipulation/var/rscriptType.js
index 0c77c8a..7237c8a 100644
--- a/src/manipulation/var/rscriptType.js
+++ b/src/manipulation/var/rscriptType.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /^$|\/(?:java|ecma)script/i );
} );
diff --git a/src/manipulation/var/rtagName.js b/src/manipulation/var/rtagName.js
index 1f8751e..d565dd3 100644
--- a/src/manipulation/var/rtagName.js
+++ b/src/manipulation/var/rtagName.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
} );
diff --git a/src/manipulation/wrapMap.js b/src/manipulation/wrapMap.js
index fdb430a..1f446f7 100644
--- a/src/manipulation/wrapMap.js
+++ b/src/manipulation/wrapMap.js
@@ -1,9 +1,11 @@
define( function() {
+"use strict";
+
// We have to close these tags to support XHTML (#13200)
var wrapMap = {
- // Support: IE9
+ // Support: IE <=9 only
option: [ 1, "<select multiple='multiple'>", "</select>" ],
// XHTML parsers do not magically insert elements in the
@@ -17,7 +19,7 @@ var wrapMap = {
_default: [ 0, "", "" ]
};
-// Support: IE9
+// Support: IE <=9 only
wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
diff --git a/src/offset.js b/src/offset.js
index f7ef79c..54442eb 100644
--- a/src/offset.js
+++ b/src/offset.js
@@ -13,6 +13,8 @@ define( [
"./selector" // contains
], function( jQuery, access, document, documentElement, rnumnonpx, curCSS, addGetHookIf, support ) {
+"use strict";
+
/**
* Gets a window from an element
*/
@@ -91,7 +93,7 @@ jQuery.fn.extend( {
return;
}
- // Support: IE<=11+
+ // Support: IE <=11 only
// Running getBoundingClientRect on a
// disconnected node in IE throws an error
if ( !elem.getClientRects().length ) {
@@ -144,11 +146,10 @@ jQuery.fn.extend( {
}
// Add offsetParent borders
- // Subtract offsetParent scroll positions
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ) -
- offsetParent.scrollTop();
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) -
- offsetParent.scrollLeft();
+ parentOffset = {
+ top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
+ left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
+ };
}
// Subtract parent offsets and element margins
@@ -206,10 +207,10 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(
};
} );
-// Support: Safari<7-8+, Chrome<37-44+
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
diff --git a/src/outro.js b/src/outro.js
deleted file mode 100644
index d792ffb..0000000
--- a/src/outro.js
+++ /dev/null
@@ -1,2 +0,0 @@
-return jQuery;
-}));
diff --git a/src/queue.js b/src/queue.js
index 813c41c..3a626a2 100644
--- a/src/queue.js
+++ b/src/queue.js
@@ -5,6 +5,8 @@ define( [
"./callbacks"
], function( jQuery, dataPriv ) {
+"use strict";
+
jQuery.extend( {
queue: function( elem, type, data ) {
var queue;
diff --git a/src/queue/delay.js b/src/queue/delay.js
index 4def286..d471eed 100644
--- a/src/queue/delay.js
+++ b/src/queue/delay.js
@@ -4,6 +4,8 @@ define( [
"../effects" // Delay is optional because of this dependency
], function( jQuery ) {
+"use strict";
+
// Based off of the plugin by Clint Helfers, with permission.
// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
jQuery.fn.delay = function( time, type ) {
diff --git a/src/selector-native.js b/src/selector-native.js
index ee81483..da837a0 100644
--- a/src/selector-native.js
+++ b/src/selector-native.js
@@ -6,6 +6,8 @@ define( [
"./var/indexOf"
], function( jQuery, document, documentElement, hasOwn, indexOf ) {
+"use strict";
+
/*
* Optional (non-Sizzle) selector module for custom builds.
*
@@ -37,7 +39,26 @@ var hasDuplicate, sortInput,
documentElement.webkitMatchesSelector ||
documentElement.mozMatchesSelector ||
documentElement.oMatchesSelector ||
- documentElement.msMatchesSelector;
+ documentElement.msMatchesSelector,
+
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,
+ fcssescape = function( ch, asCodePoint ) {
+ if ( asCodePoint ) {
+
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
+ }
+
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
+
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
+ };
function sortOrder( a, b ) {
@@ -110,7 +131,14 @@ function uniqueSort( results ) {
return results;
}
+function escape( sel ) {
+ return ( sel + "" ).replace( rcssescape, fcssescape );
+}
+
jQuery.extend( {
+ uniqueSort: uniqueSort,
+ unique: uniqueSort,
+ escapeSelector: escape,
find: function( selector, context, results, seed ) {
var elem, nodeType,
i = 0;
@@ -140,8 +168,6 @@ jQuery.extend( {
return results;
},
- uniqueSort: uniqueSort,
- unique: uniqueSort,
text: function( elem ) {
var node,
ret = "",
diff --git a/src/selector-sizzle.js b/src/selector-sizzle.js
index dcee45f..ff7bc70 100644
--- a/src/selector-sizzle.js
+++ b/src/selector-sizzle.js
@@ -1,14 +1,19 @@
define( [
"./core",
- "sizzle"
+ "../external/sizzle/dist/sizzle"
], function( jQuery, Sizzle ) {
+"use strict";
+
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
+
+// Deprecated
jQuery.expr[ ":" ] = jQuery.expr.pseudos;
jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
} );
diff --git a/src/selector.js b/src/selector.js
index e13f585..2e0c17e 100644
--- a/src/selector.js
+++ b/src/selector.js
@@ -1 +1,3 @@
-define( [ "./selector-sizzle" ], function() {} );
+define( [ "./selector-sizzle" ], function() {
+ "use strict";
+} );
diff --git a/src/serialize.js b/src/serialize.js
index a0b9484..35dcf04 100644
--- a/src/serialize.js
+++ b/src/serialize.js
@@ -6,6 +6,8 @@ define( [
"./attributes/prop"
], function( jQuery, rcheckableType ) {
+"use strict";
+
var
rbracket = /\[\]$/,
rCRLF = /\r?\n/g,
@@ -55,17 +57,16 @@ function buildParams( prefix, obj, traditional, add ) {
jQuery.param = function( a, traditional ) {
var prefix,
s = [],
- add = function( key, value ) {
+ add = function( key, valueOrFunction ) {
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
- };
+ // If value is a function, invoke it and use its return value
+ var value = jQuery.isFunction( valueOrFunction ) ?
+ valueOrFunction() :
+ valueOrFunction;
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
- }
+ s[ s.length ] = encodeURIComponent( key ) + "=" +
+ encodeURIComponent( value == null ? "" : value );
+ };
// If an array was passed in, assume that it is an array of form elements.
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
@@ -110,13 +111,17 @@ jQuery.fn.extend( {
.map( function( i, elem ) {
var val = jQuery( this ).val();
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val ) {
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- } ) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ if ( val == null ) {
+ return null;
+ }
+
+ if ( jQuery.isArray( val ) ) {
+ return jQuery.map( val, function( val ) {
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ } );
+ }
+
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
} ).get();
}
} );
diff --git a/src/traversing.js b/src/traversing.js
index 8525c0a..50cd2d6 100644
--- a/src/traversing.js
+++ b/src/traversing.js
@@ -9,6 +9,8 @@ define( [
"./selector"
], function( jQuery, indexOf, dir, siblings, rneedsContext ) {
+"use strict";
+
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
// Methods guaranteed to produce a unique set when starting from a unique set
diff --git a/src/traversing/findFilter.js b/src/traversing/findFilter.js
index f3a929e..3bd036a 100644
--- a/src/traversing/findFilter.js
+++ b/src/traversing/findFilter.js
@@ -5,33 +5,39 @@ define( [
"../selector"
], function( jQuery, indexOf, rneedsContext ) {
+"use strict";
+
var risSimple = /^.[^:#\[\.,]*$/;
// Implement the identical functionality for filter and not
function winnow( elements, qualifier, not ) {
if ( jQuery.isFunction( qualifier ) ) {
return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
return !!qualifier.call( elem, i, elem ) !== not;
} );
-
}
+ // Single element
if ( qualifier.nodeType ) {
return jQuery.grep( elements, function( elem ) {
return ( elem === qualifier ) !== not;
} );
-
}
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
- qualifier = jQuery.filter( qualifier, elements );
+ // Simple selector that can be filtered directly, removing non-Elements
+ if ( risSimple.test( qualifier ) ) {
+ return jQuery.filter( qualifier, elements, not );
}
+ // Complex selector, compare the two sets, removing non-Elements
+ qualifier = jQuery.filter( qualifier, elements );
return jQuery.grep( elements, function( elem ) {
return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
} );
@@ -44,18 +50,19 @@ jQuery.filter = function( expr, elems, not ) {
expr = ":not(" + expr + ")";
}
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- } ) );
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
+
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
};
jQuery.fn.extend( {
find: function( selector ) {
- var i,
+ var i, ret,
len = this.length,
- ret = [],
self = this;
if ( typeof selector !== "string" ) {
@@ -68,11 +75,13 @@ jQuery.fn.extend( {
} ) );
}
+ ret = this.pushStack( [] );
+
for ( i = 0; i < len; i++ ) {
jQuery.find( selector, self[ i ], ret );
}
- return this.pushStack( len > 1 ? jQuery.uniqueSort( ret ) : ret );
+ return len > 1 ? jQuery.uniqueSort( ret ) : ret;
},
filter: function( selector ) {
return this.pushStack( winnow( this, selector || [], false ) );
diff --git a/src/traversing/var/dir.js b/src/traversing/var/dir.js
index b98fdca..366a823 100644
--- a/src/traversing/var/dir.js
+++ b/src/traversing/var/dir.js
@@ -2,6 +2,8 @@ define( [
"../../core"
], function( jQuery ) {
+"use strict";
+
return function( elem, dir, until ) {
var matched = [],
truncate = until !== undefined;
diff --git a/src/traversing/var/rneedsContext.js b/src/traversing/var/rneedsContext.js
index f57fd9d..d0663ce 100644
--- a/src/traversing/var/rneedsContext.js
+++ b/src/traversing/var/rneedsContext.js
@@ -2,5 +2,7 @@ define( [
"../../core",
"../../selector"
], function( jQuery ) {
+ "use strict";
+
return jQuery.expr.match.needsContext;
} );
diff --git a/src/traversing/var/siblings.js b/src/traversing/var/siblings.js
index 8a8880b..952629d 100644
--- a/src/traversing/var/siblings.js
+++ b/src/traversing/var/siblings.js
@@ -1,5 +1,7 @@
define( function() {
+"use strict";
+
return function( n, elem ) {
var matched = [];
diff --git a/src/var/ObjectFunctionString.js b/src/var/ObjectFunctionString.js
new file mode 100644
index 0000000..f9e850f
--- /dev/null
+++ b/src/var/ObjectFunctionString.js
@@ -0,0 +1,7 @@
+define( [
+ "./fnToString"
+], function( fnToString ) {
+ "use strict";
+
+ return fnToString.call( Object );
+} );
diff --git a/src/var/arr.js b/src/var/arr.js
index 3fd3640..84713d8 100644
--- a/src/var/arr.js
+++ b/src/var/arr.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return [];
} );
diff --git a/src/var/class2type.js b/src/var/class2type.js
index 3a6932e..4365d46 100644
--- a/src/var/class2type.js
+++ b/src/var/class2type.js
@@ -1,4 +1,5 @@
define( function() {
+ "use strict";
// [[Class]] -> type pairs
return {};
diff --git a/src/var/concat.js b/src/var/concat.js
index 9787bea..e47c19d 100644
--- a/src/var/concat.js
+++ b/src/var/concat.js
@@ -1,5 +1,7 @@
define( [
"./arr"
], function( arr ) {
+ "use strict";
+
return arr.concat;
} );
diff --git a/src/var/document.js b/src/var/document.js
index bb94284..dd3939d 100644
--- a/src/var/document.js
+++ b/src/var/document.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return window.document;
} );
diff --git a/src/var/documentElement.js b/src/var/documentElement.js
index e0c0aea..0e3f8b4 100644
--- a/src/var/documentElement.js
+++ b/src/var/documentElement.js
@@ -1,5 +1,7 @@
define( [
"./document"
], function( document ) {
+ "use strict";
+
return document.documentElement;
} );
diff --git a/src/var/fnToString.js b/src/var/fnToString.js
new file mode 100644
index 0000000..18c43ff
--- /dev/null
+++ b/src/var/fnToString.js
@@ -0,0 +1,7 @@
+define( [
+ "./hasOwn"
+], function( hasOwn ) {
+ "use strict";
+
+ return hasOwn.toString;
+} );
diff --git a/src/var/getProto.js b/src/var/getProto.js
new file mode 100644
index 0000000..965fab8
--- /dev/null
+++ b/src/var/getProto.js
@@ -0,0 +1,5 @@
+define( function() {
+ "use strict";
+
+ return Object.getPrototypeOf;
+} );
diff --git a/src/var/hasOwn.js b/src/var/hasOwn.js
index 92f323e..44ab680 100644
--- a/src/var/hasOwn.js
+++ b/src/var/hasOwn.js
@@ -1,5 +1,7 @@
define( [
"./class2type"
], function( class2type ) {
+ "use strict";
+
return class2type.hasOwnProperty;
} );
diff --git a/src/var/indexOf.js b/src/var/indexOf.js
index 5283841..8320b98 100644
--- a/src/var/indexOf.js
+++ b/src/var/indexOf.js
@@ -1,5 +1,7 @@
define( [
"./arr"
], function( arr ) {
+ "use strict";
+
return arr.indexOf;
} );
diff --git a/src/var/pnum.js b/src/var/pnum.js
index 7fd9f66..6f06d73 100644
--- a/src/var/pnum.js
+++ b/src/var/pnum.js
@@ -1,3 +1,5 @@
define( function() {
+ "use strict";
+
return ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
} );
diff --git a/src/var/push.js b/src/var/push.js
index bca1a58..9465620 100644
--- a/src/var/push.js
+++ b/src/var/push.js
@@ -1,5 +1,7 @@
define( [
"./arr"
], function( arr ) {
+ "use strict";
+
return arr.push;
} );
diff --git a/src/var/rcssNum.js b/src/var/rcssNum.js
index 408f5e2..4214b14 100644
--- a/src/var/rcssNum.js
+++ b/src/var/rcssNum.js
@@ -2,6 +2,8 @@ define( [
"../var/pnum"
], function( pnum ) {
+"use strict";
+
return new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
} );
diff --git a/src/var/rnothtmlwhite.js b/src/var/rnothtmlwhite.js
new file mode 100644
index 0000000..30604db
--- /dev/null
+++ b/src/var/rnothtmlwhite.js
@@ -0,0 +1,8 @@
+define( function() {
+ "use strict";
+
+ // Only count HTML whitespace
+ // Other whitespace should count in values
+ // https://html.spec.whatwg.org/multipage/infrastructure.html#space-character
+ return ( /[^\x20\t\r\n\f]+/g );
+} );
diff --git a/src/var/rnotwhite.js b/src/var/rnotwhite.js
deleted file mode 100644
index 6067728..0000000
--- a/src/var/rnotwhite.js
+++ /dev/null
@@ -1,3 +0,0 @@
-define( function() {
- return ( /\S+/g );
-} );
diff --git a/src/var/slice.js b/src/var/slice.js
index d8206d3..915f837 100644
--- a/src/var/slice.js
+++ b/src/var/slice.js
@@ -1,5 +1,7 @@
define( [
"./arr"
], function( arr ) {
+ "use strict";
+
return arr.slice;
} );
diff --git a/src/var/support.js b/src/var/support.js
index 3db9b67..094d0ae 100644
--- a/src/var/support.js
+++ b/src/var/support.js
@@ -1,4 +1,5 @@
define( function() {
+ "use strict";
// All support tests are defined in their respective modules.
return {};
diff --git a/src/var/toString.js b/src/var/toString.js
index 80ac7f1..ff4ecdc 100644
--- a/src/var/toString.js
+++ b/src/var/toString.js
@@ -1,5 +1,7 @@
define( [
"./class2type"
], function( class2type ) {
+ "use strict";
+
return class2type.toString;
} );
diff --git a/src/wrap.js b/src/wrap.js
index 69c7cbf..88b9bb5 100644
--- a/src/wrap.js
+++ b/src/wrap.js
@@ -5,6 +5,8 @@ define( [
"./traversing" // parent, contents
], function( jQuery ) {
+"use strict";
+
jQuery.fn.extend( {
wrapAll: function( html ) {
var wrap;
diff --git a/src/intro.js b/src/wrapper.js
similarity index 64%
rename from src/intro.js
rename to src/wrapper.js
index 2918495..af90fb2 100644
--- a/src/intro.js
+++ b/src/wrapper.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars*/
/*!
* jQuery JavaScript Library v at VERSION
* https://jquery.com/
@@ -11,10 +12,12 @@
*
* Date: @DATE
*/
+( function( global, factory ) {
-(function( global, factory ) {
+ "use strict";
if ( typeof module === "object" && typeof module.exports === "object" ) {
+
// For CommonJS and CommonJS-like environments where a proper `window`
// is present, execute the factory and get jQuery.
// For environments that do not have a `window` with a `document`
@@ -35,10 +38,16 @@
}
// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+// @CODE
+// build.js inserts compiled jQuery here
-// Support: Firefox 18+
-// Can't be in strict mode, several libs including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-//"use strict";
+return jQuery;
+} );
diff --git a/test/.jshintrc b/test/.eslintrc.json
similarity index 54%
rename from test/.jshintrc
rename to test/.eslintrc.json
index 5516f84..744de89 100644
--- a/test/.jshintrc
+++ b/test/.eslintrc.json
@@ -1,24 +1,13 @@
{
- "boss": true,
- "curly": true,
- "eqeqeq": true,
- "eqnull": true,
- "expr": true,
- "immed": true,
- "noarg": true,
- "quotmark": "double",
- "undef": true,
- "unused": true,
-
- "es3": true,
-
- "evil": true,
- "sub": true,
-
- "browser": true,
- "devel": true,
- "wsh": true,
-
+ "env": {
+ "browser": true
+ },
+ // Support: IE <=9 only, Android <=4.0 only
+ // The above browsers are failing a lot of tests in the ES5
+ // test suite at http://test262.ecmascript.org.
+ "parserOptions": {
+ "ecmaVersion": 3
+ },
"globals": {
"require": false,
"define": false,
@@ -38,7 +27,6 @@
"url": false,
"t": false,
"q": false,
-
"jQuery": true,
"sinon": true,
"amdDefined": true,
@@ -52,5 +40,19 @@
"original$": true,
"baseURL": true,
"externalHost": true
+ },
+ "rules": {
+ // See https://github.com/eslint/eslint/issues/2342
+ "no-unused-vars": "off",
+
+ // Too much errors
+ "max-len": "off",
+ "brace-style": "off",
+ "key-spacing": "off",
+ "camelcase": "off",
+
+ // Not really too much - waiting autofix features for these rules
+ "lines-around-comment": "off",
+ "dot-notation": "off"
}
}
diff --git a/test/data/ajax/onunload.html b/test/data/ajax/onunload.html
index eb1bca2..ec6e4b7 100644
--- a/test/data/ajax/onunload.html
+++ b/test/data/ajax/onunload.html
@@ -4,6 +4,7 @@
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title>onunload ajax requests (#14379)</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<form id="navigate" action="../iframe.html"></form>
@@ -17,7 +18,7 @@
ajaxStatus = status;
}
});
- parent.iframeCallback( ajaxStatus );
+ startIframeTest( ajaxStatus );
});
jQuery(function() {
diff --git a/test/data/ajax/unreleasedXHR.html b/test/data/ajax/unreleasedXHR.html
index 8a41c49..3eedaab 100644
--- a/test/data/ajax/unreleasedXHR.html
+++ b/test/data/ajax/unreleasedXHR.html
@@ -4,13 +4,14 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Attempt to block tests because of dangling XHR requests (IE)</title>
<script src="../../jquery.js"></script>
+<script src="../iframeTest.js"></script>
<script type="text/javascript">
window.onunload = function() {};
jQuery(function() {
setTimeout(function() {
var parent = window.parent;
document.write("");
- parent.iframeCallback();
+ startIframeTest();
}, 200 );
var number = 50;
while( number-- ) {
diff --git a/test/data/core/aliased.html b/test/data/core/aliased.html
index ed06606..87b5871 100644
--- a/test/data/core/aliased.html
+++ b/test/data/core/aliased.html
@@ -10,15 +10,16 @@
};
</script>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<form>
<input type="text" id="nodeName"/>
</form>
<script>
- jQuery(function() {
- window.parent.iframeCallback( errors );
- });
+ jQuery( function() {
+ startIframeTest( errors );
+ } );
</script>
</body>
</html>
diff --git a/test/data/core/cc_on.html b/test/data/core/cc_on.html
index 131e2e8..5db1891 100644
--- a/test/data/core/cc_on.html
+++ b/test/data/core/cc_on.html
@@ -13,10 +13,11 @@
};
</script>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<script>
- window.parent.iframeCallback( cc_on, errors, jQuery );
+ startIframeTest( cc_on, errors );
</script>
</body>
</html>
diff --git a/test/data/core/dynamic_ready.html b/test/data/core/dynamic_ready.html
index 3b29c11..1db068b 100644
--- a/test/data/core/dynamic_ready.html
+++ b/test/data/core/dynamic_ready.html
@@ -4,6 +4,7 @@
<meta charset="utf-8">
<script src="../../jquery.js"></script>
<script>var $j = jQuery.noConflict();</script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<iframe id="dont_return" src="dont_return.php"></iframe>
@@ -20,14 +21,14 @@
$(function () {
clearTimeout( timeoutId );
if ( !timeoutFired ) {
- window.parent.iframeCallback( true );
+ startIframeTest( true );
}
});
});
timeoutId = setTimeout(function () {
timeoutFired = true;
- window.parent.iframeCallback( false );
+ startIframeTest( false );
}, 10000);
});
</script>
diff --git a/test/data/core/onready.html b/test/data/core/onready.html
index 1e8f127..88ba94a 100644
--- a/test/data/core/onready.html
+++ b/test/data/core/onready.html
@@ -8,6 +8,7 @@
window.onready = function() { error = "Called window.onready"; };
</script>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<form>
@@ -16,7 +17,7 @@
<script>
jQuery(function() {
setTimeout( function() {
- window.parent.iframeCallback( error );
+ startIframeTest( error );
});
});
</script>
diff --git a/test/data/css/cssWidthBeforeDocReady.html b/test/data/css/cssWidthBeforeDocReady.html
index 12e954d..4ebc2c9 100644
--- a/test/data/css/cssWidthBeforeDocReady.html
+++ b/test/data/css/cssWidthBeforeDocReady.html
@@ -4,7 +4,6 @@
<meta charset="utf-8">
<style>
#test {
- -webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100px;
height: 100px;
@@ -15,8 +14,9 @@
<body>
<div id="test"></div>
<script src="../../jquery.js"></script>
+<script src="../iframeTest.js"></script>
<script>
- window.parent.iframeCallback( jQuery( "#test" ).css( 'width' ) );
+ startIframeTest( jQuery( "#test" ).css( 'width' ) );
</script>
</body>
</html>
diff --git a/test/data/data/dataAttrs.html b/test/data/data/dataAttrs.html
index 5e6e442..785150e 100644
--- a/test/data/data/dataAttrs.html
+++ b/test/data/data/dataAttrs.html
@@ -4,9 +4,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IE11 onpageshow strangeness (#14894)</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script>
$(function(){
- window.parent.iframeCallback( $( "body" ).data().result );
+ startIframeTest( $( "body" ).data().result );
});
</script>
</head>
diff --git a/test/data/dimensions/documentLarge.html b/test/data/dimensions/documentLarge.html
index a6598fc..9d6a729 100644
--- a/test/data/dimensions/documentLarge.html
+++ b/test/data/dimensions/documentLarge.html
@@ -8,10 +8,14 @@
height: 1000px;
}
</style>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<div>
<script src="../../jquery.js"></script>
+ <script>
+ jQuery( startIframeTest );
+ </script>
</div>
</body>
</html>
diff --git a/test/data/event/focusElem.html b/test/data/event/focusElem.html
index a9a9765..1940e8b 100644
--- a/test/data/event/focusElem.html
+++ b/test/data/event/focusElem.html
@@ -5,12 +5,13 @@
<title>.focus() (activeElement access #13393)</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<a href="#" id="frame-link"></a>
<script>
jQuery( "#frame-link" ).trigger( "focus" );
- window.parent.iframeCallback( true );
+ startIframeTest( true );
</script>
</body>
</html>
diff --git a/test/data/event/focusinCrossFrame.html b/test/data/event/focusinCrossFrame.html
index 487f8de..6dd187e 100644
--- a/test/data/event/focusinCrossFrame.html
+++ b/test/data/event/focusinCrossFrame.html
@@ -5,13 +5,14 @@
<title>focusin event cross-frame (#14180)</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
</head>
<body>
<input type="text" id="frame-input" />
<script>
// Call parent when this frame is fully loaded, it will mess with #frame-input
jQuery( window ).one( "load", function() {
- window.parent.iframeCallback( document );
+ startIframeTest();
});
</script>
</body>
diff --git a/test/data/event/interactiveReady.html b/test/data/event/interactiveReady.html
index 77b3710..3fb25f9 100644
--- a/test/data/event/interactiveReady.html
+++ b/test/data/event/interactiveReady.html
@@ -4,13 +4,14 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test case for gh-2100</title>
<script src="../../jquery.js"></script>
+<script src="../iframeTest.js"></script>
</head>
<body>
<script type="text/javascript">
-jQuery( document ).ready(function () {
- window.parent.iframeCallback( jQuery("#container").length === 1 );
-});
+jQuery( function () {
+ startIframeTest( jQuery("#container").length === 1 );
+} );
</script>
<!-- external resources that come before elements trick
diff --git a/test/data/event/promiseReady.html b/test/data/event/promiseReady.html
index 17b6e7f..c6e0862 100644
--- a/test/data/event/promiseReady.html
+++ b/test/data/event/promiseReady.html
@@ -4,10 +4,11 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test case for jQuery ticket #11470</title>
<script src="../../jquery.js"></script>
+<script src="../iframeTest.js"></script>
<script type="text/javascript">
jQuery.when( jQuery.ready ).done(function() {
jQuery("body").append("<div>modifying DOM</div>");
- window.parent.iframeCallback( $("div").text() === "modifying DOM" );
+ startIframeTest( $("div").text() === "modifying DOM" );
});
</script>
</head>
diff --git a/test/data/event/syncReady.html b/test/data/event/syncReady.html
index dfa9ac3..61a50e4 100644
--- a/test/data/event/syncReady.html
+++ b/test/data/event/syncReady.html
@@ -4,12 +4,13 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test case for jQuery ticket #10067</title>
<script src="../../jquery.js"></script>
+<script src="../iframeTest.js"></script>
</head>
<body>
<script type="text/javascript">
jQuery( document ).ready(function () {
- window.parent.iframeCallback( jQuery('#container').length === 1 );
+ startIframeTest( jQuery('#container').length === 1 );
});
</script>
diff --git a/test/data/event/triggerunload.html b/test/data/event/triggerunload.html
index a7879c7..02be59d 100644
--- a/test/data/event/triggerunload.html
+++ b/test/data/event/triggerunload.html
@@ -1,6 +1,7 @@
<!doctype html>
<html>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script>
var called = false,
error = false;
@@ -12,7 +13,7 @@
return "maybe";
}).on( "load", function( event ) {
$( window ).triggerHandler( "beforeunload" );
- window.parent.iframeCallback( called && !error );
+ startIframeTest( called && !error );
});
</script>
</html>
diff --git a/test/data/iframeTest.js b/test/data/iframeTest.js
new file mode 100644
index 0000000..877e884
--- /dev/null
+++ b/test/data/iframeTest.js
@@ -0,0 +1,8 @@
+
+window.startIframeTest = function() {
+ var args = Array.prototype.slice.call( arguments );
+
+ // Note: jQuery may be undefined if page did not load it
+ args.unshift( window.jQuery, window, document );
+ window.parent.iframeCallback.apply( null, args );
+};
diff --git a/test/data/manipulation/iframe-denied.html b/test/data/manipulation/iframe-denied.html
index 14df26a..e74872a 100644
--- a/test/data/manipulation/iframe-denied.html
+++ b/test/data/manipulation/iframe-denied.html
@@ -7,6 +7,7 @@
<body>
<div id="qunit-fixture"></div>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script>
var script = document.getElementsByTagName( "script" )[ 0 ],
div = document.createElement( "div" ),
@@ -25,7 +26,7 @@
error = e;
}
- window.parent.iframeCallback({
+ startIframeTest({
status: success,
description: "buildFragment sets the context without throwing an exception" +
( error ? ": " + error : "" )
diff --git a/test/data/manipulation/scripts-context.html b/test/data/manipulation/scripts-context.html
index 6958453..1b75e3a 100644
--- a/test/data/manipulation/scripts-context.html
+++ b/test/data/manipulation/scripts-context.html
@@ -7,12 +7,9 @@
<body>
<div id="qunit-fixture"></div>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script>
- window.parent.iframeCallback(
- window,
- document.body,
- "<script>window.scriptTest = true;<\x2fscript>"
- );
+ startIframeTest();
</script>
</body>
</html>
diff --git a/test/data/offset/absolute.html b/test/data/offset/absolute.html
index 58f0cbd..9d87004 100644
--- a/test/data/offset/absolute.html
+++ b/test/data/offset/absolute.html
@@ -16,6 +16,7 @@
#positionTest { position: absolute; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
$(".absolute").click(function() {
@@ -24,6 +25,7 @@
$(this).css({ top: pos.top, left: pos.left });
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/body.html b/test/data/offset/body.html
index c0de297..75757d7 100644
--- a/test/data/offset/body.html
+++ b/test/data/offset/body.html
@@ -10,12 +10,14 @@
#firstElement { width: 50px; height: 50px; background: green; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
$("body").click(function() {
$("marker").css( $(this).offset() );
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/fixed.html b/test/data/offset/fixed.html
index c695ba4..48a2c47 100644
--- a/test/data/offset/fixed.html
+++ b/test/data/offset/fixed.html
@@ -13,6 +13,7 @@
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
window.scrollTo(1000,1000);
@@ -20,6 +21,7 @@
$("#marker").css( $(this).offset() );
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/relative.html b/test/data/offset/relative.html
index f88c82a..288fd4e 100644
--- a/test/data/offset/relative.html
+++ b/test/data/offset/relative.html
@@ -12,6 +12,7 @@
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
$(".relative").click(function() {
@@ -20,6 +21,7 @@
$(this).css({ position: 'absolute', top: pos.top, left: pos.left });
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/scroll.html b/test/data/offset/scroll.html
index c8c0802..28cade1 100644
--- a/test/data/offset/scroll.html
+++ b/test/data/offset/scroll.html
@@ -15,6 +15,7 @@
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
window.scrollTo(1000,1000);
@@ -24,6 +25,7 @@
$("#marker").css( $(this).offset() );
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/static.html b/test/data/offset/static.html
index f8cafa8..1f4c3dc 100644
--- a/test/data/offset/static.html
+++ b/test/data/offset/static.html
@@ -11,6 +11,7 @@
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
$(".static").click(function() {
@@ -19,6 +20,7 @@
$(this).css({ position: 'absolute', top: pos.top, left: pos.left });
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/offset/table.html b/test/data/offset/table.html
index ff2b857..eeac19b 100644
--- a/test/data/offset/table.html
+++ b/test/data/offset/table.html
@@ -11,12 +11,14 @@
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script type="text/javascript" charset="utf-8">
jQuery(function($) {
$("table, th, td").click(function() {
$("#marker").css( $(this).offset() );
return false;
});
+ startIframeTest();
});
</script>
</head>
diff --git a/test/data/selector/html5_selector.html b/test/data/selector/html5_selector.html
index 30f25c9..35c583c 100644
--- a/test/data/selector/html5_selector.html
+++ b/test/data/selector/html5_selector.html
@@ -5,7 +5,7 @@
<title>jQuery selector - attributes</title>
<script src="../../jquery.js"></script>
-
+ <script src="../iframeTest.js"></script>
<script id="script1"
defer
async></script>
@@ -15,6 +15,8 @@
document.createElement('audio');
document.createElement('article');
document.createElement('details');
+
+ jQuery( startIframeTest );
</script>
</head>
<body>
diff --git a/test/data/selector/sizzle_cache.html b/test/data/selector/sizzle_cache.html
index 1055c75..513390c 100644
--- a/test/data/selector/sizzle_cache.html
+++ b/test/data/selector/sizzle_cache.html
@@ -5,6 +5,7 @@
<title>jQuery selector - sizzle cache</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script>
document.write(
"<script>var $cached = jQuery.noConflict(true);<\x2Fscript>" +
@@ -17,5 +18,8 @@
<div class="test">
<a href="#" id="collision">Worlds collide</a>
</div>
+ <script>
+ jQuery( startIframeTest );
+ </script>
</body>
</html>
diff --git a/test/data/support/bodyBackground.html b/test/data/support/bodyBackground.html
index cac0998..d95f39d 100644
--- a/test/data/support/bodyBackground.html
+++ b/test/data/support/bodyBackground.html
@@ -18,10 +18,11 @@
<body>
<div>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script src="getComputedSupport.js"></script>
</div>
<script>
- window.parent.iframeCallback( jQuery( "body" ).css( "backgroundColor" ),
+ startIframeTest( jQuery( "body" ).css( "backgroundColor" ),
getComputedSupport( jQuery.support ) );
</script>
</body>
diff --git a/test/data/support/csp.js b/test/data/support/csp.js
index 5ebdcea..4d55bda 100644
--- a/test/data/support/csp.js
+++ b/test/data/support/csp.js
@@ -1,3 +1,3 @@
jQuery( function() {
- parent.iframeCallback( getComputedSupport( jQuery.support ) );
+ startIframeTest( getComputedSupport( jQuery.support ) );
} );
diff --git a/test/data/support/csp.php b/test/data/support/csp.php
index 0783e17..4460002 100644
--- a/test/data/support/csp.php
+++ b/test/data/support/csp.php
@@ -9,6 +9,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CSP Test Page</title>
<script src="../../jquery.js"></script>
+ <script src="../iframeTest.js"></script>
<script src="csp.js"></script>
<script src="getComputedSupport.js"></script>
</head>
diff --git a/test/data/test3.html b/test/data/test3.html
index a7f862a..446d5c1 100644
--- a/test/data/test3.html
+++ b/test/data/test3.html
@@ -2,3 +2,4 @@
<div class="user">This is a user</div>
<div class="teacher">This is a teacher</div>
<div id="superuser">This is a superuser</div>
+<div id="whitespace\xA0">This is a superuser with non-HTML whitespace</div>
diff --git a/test/data/testinit.js b/test/data/testinit.js
index ca8f433..ef210e7 100644
--- a/test/data/testinit.js
+++ b/test/data/testinit.js
@@ -1,7 +1,6 @@
-/*jshint multistr:true, quotmark:false */
+/* eslint no-multi-str: "off" */
-var fireNative, originaljQuery, original$,
- baseURL = "",
+var baseURL = "",
supportjQuery = this.jQuery,
// see RFC 2606
@@ -12,8 +11,8 @@ this.isLocal = window.location.protocol === "file:";
// Setup global variables before loading jQuery for testing .noConflict()
supportjQuery.noConflict( true );
-originaljQuery = this.jQuery = undefined;
-original$ = this.$ = "replaced";
+window.originaljQuery = this.jQuery = undefined;
+window.original$ = this.$ = "replaced";
/**
* Returns an array of elements with the given IDs
@@ -32,57 +31,81 @@ this.q = function() {
/**
* Asserts that a select matches the given IDs
- * @param {String} a - Assertion name
- * @param {String} b - Sizzle selector
- * @param {String} c - Array of ids to construct what is expected
- * @example t("Check for something", "//[a]", ["foo", "bar"]);
- * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'bar'
+ * @param {String} message - Assertion name
+ * @param {String} selector - Sizzle selector
+ * @param {String} expectedIds - Array of ids to construct what is expected
+ * @param {(String|Node)=document} context - Selector context
+ * @example match("Check for something", "p", ["foo", "bar"]);
*/
-QUnit.assert.t = function( a, b, c ) {
- var f = jQuery( b ).get(),
+function match( message, selector, expectedIds, context ) {
+ var f = jQuery( selector, context ).get(),
s = "",
i = 0;
for ( ; i < f.length; i++ ) {
- s += ( s && "," ) + '"' + f[ i ].id + '"';
+ s += ( s && "," ) + "\"" + f[ i ].id + "\"";
}
- this.deepEqual( f, q.apply( q, c ), a + " (" + b + ")" );
+ this.deepEqual( f, q.apply( q, expectedIds ), message + " (" + selector + ")" );
+}
+
+/**
+ * Asserts that a select matches the given IDs.
+ * The select is not bound by a context.
+ * @param {String} message - Assertion name
+ * @param {String} selector - Sizzle selector
+ * @param {String} expectedIds - Array of ids to construct what is expected
+ * @example t("Check for something", "p", ["foo", "bar"]);
+ */
+QUnit.assert.t = function( message, selector, expectedIds ) {
+ match( message, selector, expectedIds, undefined );
+};
+
+/**
+ * Asserts that a select matches the given IDs.
+ * The select is performed within the `#qunit-fixture` context.
+ * @param {String} message - Assertion name
+ * @param {String} selector - Sizzle selector
+ * @param {String} expectedIds - Array of ids to construct what is expected
+ * @example selectInFixture("Check for something", "p", ["foo", "bar"]);
+ */
+QUnit.assert.selectInFixture = function( message, selector, expectedIds ) {
+ match( message, selector, expectedIds, "#qunit-fixture" );
};
this.createDashboardXML = function() {
- var string = '<?xml version="1.0" encoding="UTF-8"?> \
+ var string = "<?xml version='1.0' encoding='UTF-8'?> \
<dashboard> \
- <locations class="foo"> \
- <location for="bar" checked="different"> \
- <infowindowtab normal="ab" mixedCase="yes"> \
- <tab title="Location"><![CDATA[blabla]]></tab> \
- <tab title="Users"><![CDATA[blublu]]></tab> \
+ <locations class='foo'> \
+ <location for='bar' checked='different'> \
+ <infowindowtab normal='ab' mixedCase='yes'> \
+ <tab title='Location'><![CDATA[blabla]]></tab> \
+ <tab title='Users'><![CDATA[blublu]]></tab> \
</infowindowtab> \
</location> \
</locations> \
- </dashboard>';
+ </dashboard>";
return jQuery.parseXML( string );
};
this.createWithFriesXML = function() {
- var string = '<?xml version="1.0" encoding="UTF-8"?> \
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" \
- xmlns:xsd="http://www.w3.org/2001/XMLSchema" \
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> \
+ var string = "<?xml version='1.0' encoding='UTF-8'?> \
+ <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' \
+ xmlns:xsd='http://www.w3.org/2001/XMLSchema' \
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> \
<soap:Body> \
- <jsconf xmlns="http://{{ externalHost }}/ns1"> \
- <response xmlns:ab="http://{{ externalHost }}/ns2"> \
+ <jsconf xmlns='http://{{ externalHost }}/ns1'> \
+ <response xmlns:ab='http://{{ externalHost }}/ns2'> \
<meta> \
- <component id="seite1" class="component"> \
- <properties xmlns:cd="http://{{ externalHost }}/ns3"> \
- <property name="prop1"> \
+ <component id='seite1' class='component'> \
+ <properties xmlns:cd='http://{{ externalHost }}/ns3'> \
+ <property name='prop1'> \
<thing /> \
<value>1</value> \
</property> \
- <property name="prop2"> \
- <thing att="something" /> \
+ <property name='prop2'> \
+ <thing att='something' /> \
</property> \
<foo_bar>foo</foo_bar> \
</properties> \
@@ -91,7 +114,7 @@ this.createWithFriesXML = function() {
</response> \
</jsconf> \
</soap:Body> \
- </soap:Envelope>';
+ </soap:Envelope>";
return jQuery.parseXML( string.replace( /\{\{\s*externalHost\s*\}\}/g, externalHost ) );
};
@@ -99,7 +122,7 @@ this.createWithFriesXML = function() {
this.createXMLFragment = function() {
var xml, frag;
if ( window.ActiveXObject ) {
- xml = new ActiveXObject( "msxml2.domdocument" );
+ xml = new window.ActiveXObject( "msxml2.domdocument" );
} else {
xml = document.implementation.createDocument( "", "", null );
}
@@ -111,7 +134,7 @@ this.createXMLFragment = function() {
return frag;
};
-fireNative = document.createEvent ?
+window.fireNative = document.createEvent ?
function( node, type ) {
var event = document.createEvent( "HTMLEvents" );
@@ -208,46 +231,15 @@ this.ajaxTest = function( title, expect, options ) {
} );
};
-this.testIframe = function( fileName, name, fn ) {
- QUnit.test( name, function( assert ) {
- var done = assert.async();
-
- // load fixture in iframe
- var iframe = loadFixture(),
- win = iframe.contentWindow,
- interval = setInterval( function() {
- if ( win && win.jQuery && win.jQuery.isReady ) {
- clearInterval( interval );
-
- // call actual tests passing the correct jQuery instance to use
- fn.call( this, win.jQuery, win, win.document, assert );
- done();
- document.body.removeChild( iframe );
- iframe = null;
- }
- }, 15 );
- } );
-
- function loadFixture() {
- var src = url( "./data/" + fileName + ".html" ),
- iframe = jQuery( "<iframe />" ).appendTo( "body" )[ 0 ];
- iframe.style.cssText = "width: 500px; height: 500px; position: absolute; " +
- "top: -600px; left: -600px; visibility: hidden;";
-
- iframe.contentWindow.location = src;
- return iframe;
- }
-};
-
-this.testIframeWithCallback = function( title, fileName, func ) {
- QUnit.test( title, 1, function( assert ) {
+this.testIframe = function( title, fileName, func ) {
+ QUnit.test( title, function( assert ) {
var iframe;
var done = assert.async();
window.iframeCallback = function() {
var args = Array.prototype.slice.call( arguments );
- args.push( assert );
+ args.unshift( assert );
setTimeout( function() {
this.iframeCallback = undefined;
@@ -255,7 +247,6 @@ this.testIframeWithCallback = function( title, fileName, func ) {
func.apply( this, args );
func = function() {};
iframe.remove();
-
done();
} );
};
@@ -269,9 +260,10 @@ this.iframeCallback = undefined;
// Tests are always loaded async
QUnit.config.autostart = false;
this.loadTests = function() {
+
// Leverage QUnit URL parsing to detect testSwarm environment and "basic" testing mode
- var loadSwarm = ( QUnit.urlParams[ "swarmURL" ] + "" ).indexOf( "http" ) === 0,
- basicTests = ( QUnit.urlParams[ "module" ] + "" ) === "basic";
+ QUnit.isSwarm = ( QUnit.urlParams.swarmURL + "" ).indexOf( "http" ) === 0;
+ QUnit.basicTests = ( QUnit.urlParams.module + "" ) === "basic";
// Get testSubproject from testrunner first
require( [ "data/testrunner.js" ], function() {
@@ -311,7 +303,7 @@ this.loadTests = function() {
var dep = tests[ i++ ];
if ( dep ) {
- if ( !basicTests || i === 1 ) {
+ if ( !QUnit.basicTests || i === 1 ) {
require( [ dep ], loadDep );
// Support: Android 2.3 only
@@ -328,12 +320,10 @@ this.loadTests = function() {
/**
* Run in noConflict mode
*/
- if ( jQuery.noConflict ) {
- jQuery.noConflict();
- }
+ jQuery.noConflict();
// Load the TestSwarm listener if swarmURL is in the address.
- if ( loadSwarm ) {
+ if ( QUnit.isSwarm ) {
require( [ "http://swarm.jquery.org/js/inject.js?" + ( new Date() ).getTime() ],
function() {
QUnit.start();
diff --git a/test/data/testsuite.css b/test/data/testsuite.css
index 253bea9..f6225df 100644
--- a/test/data/testsuite.css
+++ b/test/data/testsuite.css
@@ -53,11 +53,11 @@ div.medopacity {
}
div.nowidth {
- width: 0px;
+ width: 0;
}
div.noheight {
- height: 0px;
+ height: 0;
}
div.noopacity {
@@ -130,3 +130,15 @@ section { background:#f0f; display:block; }
.inline { display: inline; }
.list-item { display: list-item; }
.hidden, .none { display: none; }
+
+#div-gh-2836 {
+ position: relative;
+ overflow: auto;
+ height: 100px;
+}
+#div-gh-2836 div {
+ position: relative;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/test/index.html b/test/index.html
index fa515c8..1e6343d 100644
--- a/test/index.html
+++ b/test/index.html
@@ -14,7 +14,7 @@
<script src="../external/qunit/qunit.js"></script>
<script src="../external/qunit-assert-step/qunit-assert-step.js"></script>
- <script src="../external/sinon/sinon-1.14.1.js"></script>
+ <script src="../external/sinon/sinon.js"></script>
<script src="../external/npo/npo.js"></script>
<script src="../external/requirejs/require.js"></script>
<!-- See testinit for the list of tests -->
diff --git a/test/jquery.js b/test/jquery.js
index 233e696..8119d3f 100644
--- a/test/jquery.js
+++ b/test/jquery.js
@@ -18,10 +18,7 @@
// This detection allows AMD tests to be run in an iframe
if ( QUnit.urlParams.amd && window.QUnit ) {
require.config( {
- baseUrl: path,
- paths: {
- sizzle: "external/sizzle/dist/sizzle"
- }
+ baseUrl: path
} );
src = "src/jquery";
diff --git a/test/node_smoke_tests/.eslintrc.json b/test/node_smoke_tests/.eslintrc.json
new file mode 100644
index 0000000..0877d24
--- /dev/null
+++ b/test/node_smoke_tests/.eslintrc.json
@@ -0,0 +1,7 @@
+{
+ "env": {
+ "es6": true
+ },
+ "extends" : "../../.eslintrc.json",
+ "root": true
+}
diff --git a/test/node_smoke_tests/.jshintrc b/test/node_smoke_tests/.jshintrc
deleted file mode 100644
index 1445c7b..0000000
--- a/test/node_smoke_tests/.jshintrc
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "boss": true,
- "curly": true,
- "eqeqeq": true,
- "eqnull": true,
- "expr": true,
- "immed": true,
- "noarg": true,
- "quotmark": "double",
- "undef": true,
- "unused": true,
-
- "node": true
-}
diff --git a/test/node_smoke_tests/iterable_with_symbol_polyfill.js b/test/node_smoke_tests/iterable_with_symbol_polyfill.js
index dd377f1..34701d6 100644
--- a/test/node_smoke_tests/iterable_with_symbol_polyfill.js
+++ b/test/node_smoke_tests/iterable_with_symbol_polyfill.js
@@ -1,5 +1,3 @@
-/* jshint esnext: true */
-
"use strict";
var assert = require( "assert" );
diff --git a/test/node_smoke_tests/lib/ensure_iterability_es6.js b/test/node_smoke_tests/lib/ensure_iterability_es6.js
index ebe6853..8e2396d 100644
--- a/test/node_smoke_tests/lib/ensure_iterability_es6.js
+++ b/test/node_smoke_tests/lib/ensure_iterability_es6.js
@@ -1,5 +1,3 @@
-/* jshint esnext: true */
-
"use strict";
var assert = require( "assert" );
diff --git a/test/promises_aplus_adapters/.eslintrc.json b/test/promises_aplus_adapters/.eslintrc.json
new file mode 100644
index 0000000..d117757
--- /dev/null
+++ b/test/promises_aplus_adapters/.eslintrc.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../.eslintrc.json",
+ "root": true
+}
diff --git a/test/promises_aplus_adapter.js b/test/promises_aplus_adapters/deferred.js
similarity index 76%
rename from test/promises_aplus_adapter.js
rename to test/promises_aplus_adapters/deferred.js
index c7440b9..31af166 100644
--- a/test/promises_aplus_adapter.js
+++ b/test/promises_aplus_adapters/deferred.js
@@ -1,5 +1,3 @@
-/* jshint node: true */
-
"use strict";
require( "jsdom" ).env( "", function( errors, window ) {
@@ -8,9 +6,9 @@ require( "jsdom" ).env( "", function( errors, window ) {
return;
}
- var jQuery = require( ".." )( window );
+ var jQuery = require( "../../" )( window );
- exports.deferred = function() {
+ module.exports.deferred = function() {
var deferred = jQuery.Deferred();
return {
diff --git a/test/promises_aplus_adapters/when.js b/test/promises_aplus_adapters/when.js
new file mode 100644
index 0000000..adde1a1
--- /dev/null
+++ b/test/promises_aplus_adapters/when.js
@@ -0,0 +1,49 @@
+"use strict";
+
+require( "jsdom" ).env( "", function( errors, window ) {
+ if ( errors ) {
+ console.error( errors );
+ return;
+ }
+
+ var jQuery = require( "../../" )( window );
+
+ module.exports.deferred = function() {
+ var adopted, promised,
+ obj = {
+ resolve: function() {
+ if ( !adopted ) {
+ adopted = jQuery.when.apply( jQuery, arguments );
+ if ( promised ) {
+ adopted.then( promised.resolve, promised.reject );
+ }
+ }
+ return adopted;
+ },
+ reject: function( value ) {
+ if ( !adopted ) {
+ adopted = jQuery.when( jQuery.Deferred().reject( value ) );
+ if ( promised ) {
+ adopted.then( promised.resolve, promised.reject );
+ }
+ }
+ return adopted;
+ },
+
+ // A manually-constructed thenable that works even if calls precede resolve/reject
+ promise: {
+ then: function() {
+ if ( !adopted ) {
+ if ( !promised ) {
+ promised = jQuery.Deferred();
+ }
+ return promised.then.apply( promised, arguments );
+ }
+ return adopted.then.apply( adopted, arguments );
+ }
+ }
+ };
+
+ return obj;
+ };
+} );
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index 3e00afd..681aa46 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -28,7 +28,7 @@ QUnit.module( "ajax", {
//----------- jQuery.ajax()
- testIframeWithCallback(
+ testIframe(
"XMLHttpRequest - Attempt to block tests because of dangling XHR requests (IE)",
"ajax/unreleasedXHR.html",
function( assert ) {
@@ -99,7 +99,7 @@ QUnit.module( "ajax", {
assert.ok( true, "success" );
},
fail: function() {
- if (jQuery.support.cors === false) {
+ if ( jQuery.support.cors === false ) {
assert.ok( true, "fail" );
}
},
@@ -249,9 +249,8 @@ QUnit.module( "ajax", {
"Nullable": null,
"undefined": undefined
- // Support: Firefox
+ // Support: IE 9 - 11, Edge 12 - 13+
// Not all browsers allow empty-string headers
- // https://bugzilla.mozilla.org/show_bug.cgi?id=815299
//"Empty": ""
},
success: function( data, _, xhr ) {
@@ -374,6 +373,64 @@ QUnit.module( "ajax", {
];
} );
+ ajaxTest( "jQuery.ajax() - traditional param encoding", 4, function( assert ) {
+ return [
+ {
+ url: "/",
+ traditional: true,
+ data: {
+ "devo": "hat",
+ "answer": 42,
+ "quux": "a space"
+ },
+ beforeSend: function( xhr, settings ) {
+ assert.equal( settings.url, "/?devo=hat&answer=42&quux=a%20space", "Simple case" );
+ return false;
+ },
+ error: true
+ },
+ {
+ url: "/",
+ traditional: true,
+ data: {
+ "a": [ 1, 2, 3 ],
+ "b[]": [ "b1", "b2" ]
+ },
+ beforeSend: function( xhr, settings ) {
+ assert.equal( settings.url, "/?a=1&a=2&a=3&b%5B%5D=b1&b%5B%5D=b2", "Arrays" );
+ return false;
+ },
+ error: true
+ },
+ {
+ url: "/",
+ traditional: true,
+ data: {
+ "a": [ [ 1, 2 ], [ 3, 4 ], 5 ]
+ },
+ beforeSend: function( xhr, settings ) {
+ assert.equal( settings.url, "/?a=1%2C2&a=3%2C4&a=5", "Nested arrays" );
+ return false;
+ },
+ error: true
+ },
+ {
+ url: "/",
+ traditional: true,
+ data: {
+ "a": [ "w", [ [ "x", "y" ], "z" ] ]
+ },
+ cache: false,
+ beforeSend: function( xhr, settings ) {
+ var url = settings.url.replace( /\d{3,}/, "" );
+ assert.equal( url, "/?a=w&a=x%2Cy%2Cz&_=", "Cache-buster" );
+ return false;
+ },
+ error: true
+ }
+ ];
+ } );
+
ajaxTest( "jQuery.ajax() - cross-domain detection", 8, function( assert ) {
function request( url, title, crossDomainOrOptions ) {
return jQuery.extend( {
@@ -771,8 +828,9 @@ QUnit.module( "ajax", {
} ), "generic" );
} );
- ajaxTest( "jQuery.ajax() - cache", 12, function( assert ) {
- var re = /_=(.*?)(&|$)/g;
+ ajaxTest( "jQuery.ajax() - cache", 28, function( assert ) {
+ var re = /_=(.*?)(&|$)/g,
+ rootUrl = "data/text.php";
function request( url, title ) {
return {
@@ -780,6 +838,11 @@ QUnit.module( "ajax", {
cache: false,
beforeSend: function() {
var parameter, tmp;
+
+ // URL sanity check
+ assert.equal( this.url.indexOf( rootUrl ), 0, "root url not mangled: " + this.url );
+ assert.equal( /\&.*\?/.test( this.url ), false, "parameter delimiters in order" );
+
while ( ( tmp = re.exec( this.url ) ) ) {
assert.strictEqual( parameter, undefined, title + ": only one 'no-cache' parameter" );
parameter = tmp[ 1 ];
@@ -793,27 +856,31 @@ QUnit.module( "ajax", {
return [
request(
- "data/text.php",
- "no parameter"
+ rootUrl,
+ "no query"
),
request(
- "data/text.php?pizza=true",
+ rootUrl + "?",
+ "empty query"
+ ),
+ request(
+ rootUrl + "?pizza=true",
"1 parameter"
),
request(
- "data/text.php?_=tobereplaced555",
+ rootUrl + "?_=tobereplaced555",
"_= parameter"
),
request(
- "data/text.php?pizza=true&_=tobereplaced555",
+ rootUrl + "?pizza=true&_=tobereplaced555",
"1 parameter and _="
),
request(
- "data/text.php?_=tobereplaced555&tv=false",
+ rootUrl + "?_=tobereplaced555&tv=false",
"_= and 1 parameter"
),
request(
- "data/text.php?name=David&_=tobereplaced555&washere=true",
+ rootUrl + "?name=David&_=tobereplaced555&washere=true",
"2 parameters surrounding _="
)
];
@@ -1120,7 +1187,7 @@ QUnit.module( "ajax", {
},
success: function( text ) {
assert.strictEqual( typeof text, "string", "json wasn't auto-determined" );
- var json = jQuery.parseJSON( text );
+ var json = JSON.parse( text );
assert.ok( json.length >= 2, "Check length" );
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
@@ -1680,11 +1747,11 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} else {
// No built-in support for binary data, but it's easy to add via a prefilter
- jQuery.ajaxPrefilter( "arraybuffer", function ( s ) {
+ jQuery.ajaxPrefilter( "arraybuffer", function( s ) {
s.xhrFields = { responseType: "arraybuffer" };
s.responseFields.arraybuffer = "response";
s.converters[ "binary arraybuffer" ] = true;
- });
+ } );
ajaxTest( "gh-2498 - jQuery.ajax() - binary data shouldn't throw an exception", 2, function( assert ) {
return {
@@ -1699,16 +1766,6 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
}
QUnit.asyncTest( "#11743 - jQuery.ajax() - script, throws exception", 1, function( assert ) {
-
- // Support: Android 2.3 only
- // Android 2.3 doesn't fire the window.onerror handler, just accept the reality there.
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- assert.ok( true, "Test skipped, Android 2.3 doesn't fire window.onerror for " +
- "errors in dynamically included scripts" );
- QUnit.start();
- return;
- }
-
var onerror = window.onerror;
window.onerror = function() {
assert.ok( true, "Exception thrown" );
@@ -1768,13 +1825,6 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
var parsedXML = jQuery( jQuery.parseXML( "<tab title=\"Added\">blibli</tab>" ) ).find( "tab" );
ajaxXML = jQuery( ajaxXML );
try {
-
- // Android 2.3 doesn't automatically adopt nodes from foreign documents.
- // (see the comment in test/manipulation.js)
- // Support: Android 2.3
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- parsedXML = jQuery( ajaxXML[ 0 ].adoptNode( parsedXML[ 0 ] ) );
- }
ajaxXML.find( "infowindowtab" ).append( parsedXML );
} catch ( e ) {
assert.strictEqual( e, undefined, "error" );
@@ -1844,10 +1894,10 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
};
} );
- testIframeWithCallback(
+ testIframe(
"#14379 - jQuery.ajax() on unload",
"ajax/onunload.html",
- function( status, assert ) {
+ function( assert, jQuery, window, document, status ) {
assert.expect( 1 );
assert.strictEqual( status, "success", "Request completed" );
}
@@ -1921,7 +1971,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
url: url( "data/ajax/content-type.php" ),
data: {
"content-type": "test/jsontest",
- "response": JSON.stringify({test: "test"})
+ "response": JSON.stringify( { test: "test" } )
},
success: function( result ) {
assert.strictEqual(
@@ -2103,6 +2153,25 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
);
QUnit.test(
+ "jQuery#load() - should resolve with correct context", 2,
+ function( assert ) {
+ var done = assert.async();
+ var ps = jQuery( "<p></p><p></p>" );
+ var i = 0;
+
+ ps.appendTo( "#qunit-fixture" );
+
+ ps.load( "data/ajax/method.php", function() {
+ assert.strictEqual( this, ps[ i++ ] );
+
+ if ( i === 2 ) {
+ done();
+ }
+ } );
+ }
+ );
+
+ QUnit.test(
"#11402 - jQuery.domManip() - script in comments are properly evaluated", 2,
function( assert ) {
jQuery( "#qunit-fixture" ).load( "data/cleanScript.html", assert.async() );
@@ -2258,6 +2327,17 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
} );
+ // Selector should be trimmed to avoid leading spaces (#14773)
+ // Selector should include any valid non-HTML whitespace (#3003)
+ QUnit.test( "jQuery.fn.load( URL_SELECTOR with non-HTML whitespace(#3003) )", function( assert ) {
+ assert.expect( 1 );
+ var done = assert.async();
+ jQuery( "#first" ).load( "data/test3.html #whitespace\\\\xA0 ", function() {
+ assert.strictEqual( jQuery( this ).children( "div" ).length, 1, "Verify that specific elements were injected" );
+ done();
+ } );
+ } );
+
QUnit.asyncTest( "jQuery.fn.load( String, Function ) - simple: inject text into DOM", 2, function( assert ) {
jQuery( "#first" ).load( url( "data/name.html" ), function() {
assert.ok( /^ERROR/.test( jQuery( "#first" ).text() ), "Check if content was injected into the DOM" );
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index 7f92d35..1284ffd 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -128,8 +128,8 @@ QUnit.test( "attr(String)", function( assert ) {
assert.equal( jQuery( option ).prop( "selected" ), true, "Make sure that a single option is selected, even when in an optgroup." );
$img = jQuery( "<img style='display:none' width='215' height='53' src='data/1x1.jpg'/>" ).appendTo( "body" );
- assert.equal( $img.attr( "width" ), "215", "Retrieve width attribute an an element with display:none." );
- assert.equal( $img.attr( "height" ), "53", "Retrieve height attribute an an element with display:none." );
+ assert.equal( $img.attr( "width" ), "215", "Retrieve width attribute on an element with display:none." );
+ assert.equal( $img.attr( "height" ), "53", "Retrieve height attribute on an element with display:none." );
// Check for style support
styleElem = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ).css( {
@@ -220,7 +220,8 @@ QUnit.test( "attr(String, Function)", function( assert ) {
QUnit.test( "attr(Hash)", function( assert ) {
assert.expect( 3 );
var pass = true;
- jQuery( "div" ).attr( {
+
+ jQuery( "#qunit-fixture div" ).attr( {
"foo": "baz",
"zoo": "ping"
} ).each( function() {
@@ -258,7 +259,7 @@ QUnit.test( "attr(String, Object)", function( assert ) {
attributeNode, commentNode, textNode, obj,
table, td, j, type,
check, thrown, button, $radio, $radios, $svg,
- div = jQuery( "div" ).attr( "foo", "bar" ),
+ div = jQuery( "#qunit-fixture div" ).attr( "foo", "bar" ),
i = 0,
fail = false;
@@ -486,15 +487,24 @@ QUnit.test( "attr(non-ASCII)", function( assert ) {
QUnit.test( "attr - extending the boolean attrHandle", function( assert ) {
assert.expect( 1 );
var called = false,
- _handle = jQuery.expr.attrHandle.checked || $.noop;
+ origAttrHandleHadChecked = "checked" in jQuery.expr.attrHandle,
+ origAttrHandleChecked = jQuery.expr.attrHandle.checked,
+ _handle = origAttrHandleChecked || $.noop;
jQuery.expr.attrHandle.checked = function() {
called = true;
_handle.apply( this, arguments );
};
- jQuery( "input" ).attr( "checked" );
+ jQuery( "#qunit-fixture input" ).attr( "checked" );
called = false;
- jQuery( "input" ).attr( "checked" );
+ jQuery( "#qunit-fixture input" ).attr( "checked" );
assert.ok( called, "The boolean attrHandle does not drop custom attrHandles" );
+
+ if ( origAttrHandleHadChecked ) {
+ jQuery.expr.attrHandle.checked = origAttrHandleChecked;
+ } else {
+ delete jQuery.expr.attrHandle.checked;
+ }
+
} );
QUnit.test( "attr(String, Object) - Loaded via XML document", function( assert ) {
@@ -647,6 +657,28 @@ QUnit.test( "removeAttr(Multi String, variable space width)", function( assert )
} );
} );
+QUnit.test( "removeAttr(Multi String, non-HTML whitespace is valid in attribute names (gh-3003)", function( assert ) {
+ assert.expect( 8 );
+
+ var div = jQuery( "<div id='a' data-\xA0='b' title='c' rel='d'></div>" );
+ var tests = {
+ id: "a",
+ "data-\xA0": "b",
+ title: "c",
+ rel: "d"
+ };
+
+ jQuery.each( tests, function( key, val ) {
+ assert.equal( div.attr( key ), val, "Attribute \"" + key + "\" exists, and has a value of \"" + val + "\"" );
+ } );
+
+ div.removeAttr( "id data-\xA0 title rel " );
+
+ jQuery.each( tests, function( key ) {
+ assert.equal( div.attr( key ), undefined, "Attribute \"" + key + "\" was removed" );
+ } );
+} );
+
QUnit.test( "prop(String, Object)", function( assert ) {
assert.expect( 17 );
@@ -748,9 +780,9 @@ QUnit.test( "prop('tabindex')", function( assert ) {
QUnit.test( "image.prop( 'tabIndex' )", function( assert ) {
assert.expect( 1 );
- var image = jQuery("<img src='data/1x1.jpg' />")
- .appendTo("#qunit-fixture");
- assert.equal( image.prop("tabIndex" ), -1, "tabIndex on image" );
+ var image = jQuery( "<img src='data/1x1.jpg' />" )
+ .appendTo( "#qunit-fixture" );
+ assert.equal( image.prop( "tabIndex" ), -1, "tabIndex on image" );
} );
QUnit.test( "prop('tabindex', value)", function( assert ) {
@@ -796,6 +828,37 @@ QUnit.test( "prop('tabindex', value)", function( assert ) {
assert.equal( clone[ 0 ].getAttribute( "tabindex" ), "1", "set tabindex on cloned element" );
} );
+QUnit.test( "option.prop('selected', true) affects select.selectedIndex (gh-2732)", function( assert ) {
+ assert.expect( 2 );
+
+ function addOptions( $elem ) {
+ return $elem.append(
+ jQuery( "<option/>" ).val( "a" ).text( "One" ),
+ jQuery( "<option/>" ).val( "b" ).text( "Two" ),
+ jQuery( "<option/>" ).val( "c" ).text( "Three" )
+ )
+ .find( "[value=a]" ).prop( "selected", true ).end()
+ .find( "[value=c]" ).prop( "selected", true ).end();
+ }
+
+ var $optgroup,
+ $select = jQuery( "<select/>" );
+
+ // Check select with options
+ addOptions( $select ).appendTo( "#qunit-fixture" );
+ $select.find( "[value=b]" ).prop( "selected", true );
+ assert.equal( $select[ 0 ].selectedIndex, 1, "Setting option selected affects selectedIndex" );
+
+ $select.empty();
+
+ // Check select with optgroup
+ $optgroup = jQuery( "<optgroup/>" );
+ addOptions( $optgroup ).appendTo( $select );
+ $select.find( "[value=b]" ).prop( "selected", true );
+
+ assert.equal( $select[ 0 ].selectedIndex, 1, "Setting option in optgroup selected affects selectedIndex" );
+} );
+
QUnit.test( "removeProp(String)", function( assert ) {
assert.expect( 6 );
var attributeNode = document.createAttribute( "irrelevant" ),
@@ -996,7 +1059,7 @@ QUnit.test( "val(Function)", function( assert ) {
QUnit.test( "val(Array of Numbers) (Bug #7123)", function( assert ) {
assert.expect( 4 );
jQuery( "#form" ).append( "<input type='checkbox' name='arrayTest' value='1' /><input type='checkbox' name='arrayTest' value='2' /><input type='checkbox' name='arrayTest' value='3' checked='checked' /><input type='checkbox' name='arrayTest' value='4' />" );
- var elements = jQuery( "input[name=arrayTest]" ).val( [ 1, 2 ] );
+ var elements = jQuery( "#form input[name=arrayTest]" ).val( [ 1, 2 ] );
assert.ok( elements[ 0 ].checked, "First element was checked" );
assert.ok( elements[ 1 ].checked, "Second element was checked" );
assert.ok( !elements[ 2 ].checked, "Third element was unchecked" );
@@ -1075,6 +1138,75 @@ QUnit.test( "val(select) after form.reset() (Bug #2551)", function( assert ) {
jQuery( "#kk" ).remove();
} );
+QUnit.test( "select.val(space characters) (gh-2978)", function( assert ) {
+ assert.expect( 37 );
+
+ var $select = jQuery( "<select/>" ).appendTo( "#qunit-fixture" ),
+ spaces = {
+ "\\t": {
+ html: " ",
+ val: "\t"
+ },
+ "\\n": {
+ html: "
",
+ val: "\n"
+ },
+ "\\r": {
+ html: "
",
+ val: "\r"
+ },
+ "\\f": "\f",
+ "space": " ",
+ "\\u00a0": "\u00a0",
+ "\\u1680": "\u1680"
+ },
+ html = "";
+ jQuery.each( spaces, function( key, obj ) {
+ var value = obj.html || obj;
+ html += "<option value='attr" + value + "'></option>";
+ html += "<option value='at" + value + "tr'></option>";
+ html += "<option value='" + value + "attr'></option>";
+ } );
+ $select.html( html );
+
+ jQuery.each( spaces, function( key, obj ) {
+ var val = obj.val || obj;
+ $select.val( "attr" + val );
+ assert.equal( $select.val(), "attr" + val, "Value ending with space character (" + key + ") selected (attr)" );
+
+ $select.val( "at" + val + "tr" );
+ assert.equal( $select.val(), "at" + val + "tr", "Value with space character (" + key + ") in the middle selected (attr)" );
+
+ $select.val( val + "attr" );
+ assert.equal( $select.val(), val + "attr", "Value starting with space character (" + key + ") selected (attr)" );
+ } );
+
+ jQuery.each( spaces, function( key, obj ) {
+ var value = obj.html || obj,
+ val = obj.val || obj;
+ html = "";
+ html += "<option>text" + value + "</option>";
+ html += "<option>te" + value + "xt</option>";
+ html += "<option>" + value + "text</option>";
+ $select.html( html );
+
+
+ if ( /^\\u/.test( key ) ) {
+ $select.val( val + "text" );
+ assert.equal( $select.val(), val + "text", "Value with non-HTML space character at beginning is not stripped (" + key + ") selected (" + key + "text)" );
+ $select.val( "te" + val + "xt" );
+ assert.equal( $select.val(), "te" + val + "xt", "Value with non-space whitespace character (" + key + ") in the middle selected (text)" );
+ $select.val( "text" + val );
+ assert.equal( $select.val(), "text" + val, "Value with non-HTML space character at end is not stripped (" + key + ") selected (text" + key + ")" );
+ } else {
+ $select.val( "text" );
+ assert.equal( $select.val(), "text", "Value with HTML space character at beginning or end is stripped (" + key + ") selected (text)" );
+ $select.val( "te xt" );
+ assert.equal( $select.val(), "te xt", "Value with space character (" + key + ") in the middle selected (text)" );
+ }
+ } );
+} );
+
var testAddClass = function( valueObj, assert ) {
assert.expect( 9 );
@@ -1435,6 +1567,24 @@ QUnit.test( "addClass, removeClass, hasClass on many elements", function( assert
"Did not find a class when not present" );
} );
+QUnit.test( "addClass, removeClass, hasClass on elements with classes with non-HTML whitespace (gh-3072, gh-3003)", function( assert ) {
+ assert.expect( 9 );
+
+ var $elem = jQuery( "<div class=' test'></div>" );
+
+ function testMatches() {
+ assert.ok( $elem.is( ".\\A0 test" ), "Element matches with collapsed space" );
+ assert.ok( $elem.is( ".\\A0test" ), "Element matches with non-breaking space" );
+ assert.ok( $elem.hasClass( "\xA0test" ), "Element has class with non-breaking space" );
+ }
+
+ testMatches();
+ $elem.addClass( "foo" );
+ testMatches();
+ $elem.removeClass( "foo" );
+ testMatches();
+} );
+
QUnit.test( "contents().hasClass() returns correct values", function( assert ) {
assert.expect( 2 );
@@ -1491,17 +1641,22 @@ QUnit.test( "option value not trimmed when setting via parent select", function(
assert.equal( jQuery( "<select><option> 2</option></select>" ).val( "2" ).val(), "2" );
} );
-QUnit.test( "Insignificant white space returned for $(option).val() (#14858)", function( assert ) {
- assert.expect( 3 );
+QUnit.test( "Insignificant white space returned for $(option).val() (#14858, gh-2978)", function( assert ) {
+ assert.expect( 16 );
var val = jQuery( "<option></option>" ).val();
assert.equal( val.length, 0, "Empty option should have no value" );
- val = jQuery( "<option> </option>" ).val();
- assert.equal( val.length, 0, "insignificant white-space returned for value" );
+ jQuery.each( [ " ", "\n", "\t", "\f", "\r" ], function( i, character ) {
+ var val = jQuery( "<option>" + character + "</option>" ).val();
+ assert.equal( val.length, 0, "insignificant white-space returned for value" );
+
+ val = jQuery( "<option>" + character + "test" + character + "</option>" ).val();
+ assert.equal( val.length, 4, "insignificant white-space returned for value" );
- val = jQuery( "<option> test </option>" ).val();
- assert.equal( val.length, 4, "insignificant white-space returned for value" );
+ val = jQuery( "<option>te" + character + "st</option>" ).val();
+ assert.equal( val, "te st", "Whitespace is collapsed in values" );
+ } );
} );
QUnit.test( "SVG class manipulation (gh-2199)", function( assert ) {
@@ -1531,3 +1686,22 @@ QUnit.test( "SVG class manipulation (gh-2199)", function( assert ) {
assert.ok( !elem.hasClass( "awesome" ), "SVG element (" + this + ") toggles the class off" );
} );
} );
+
+QUnit.test( "non-lowercase boolean attribute getters should not crash", function( assert ) {
+ assert.expect( 3 );
+
+ var elem = jQuery( "<input checked required autofocus type='checkbox'>" );
+
+ jQuery.each( {
+ checked: "Checked",
+ required: "requiRed",
+ autofocus: "AUTOFOCUS"
+ }, function( lowercased, original ) {
+ try {
+ assert.strictEqual( elem.attr( original ), lowercased,
+ "The '" + this + "' attribute getter should return the lowercased name" );
+ } catch ( e ) {
+ assert.ok( false, "The '" + this + "' attribute getter threw" );
+ }
+ } );
+} );
diff --git a/test/unit/basic.js b/test/unit/basic.js
index 49b518d..5a2f5ab 100644
--- a/test/unit/basic.js
+++ b/test/unit/basic.js
@@ -76,7 +76,7 @@ QUnit.test( "show/hide", function( assert ) {
}
QUnit.test( "core", function( assert ) {
- assert.expect( 28 );
+ assert.expect( 27 );
var elem = jQuery( "<div></div><span></span>" );
@@ -135,8 +135,6 @@ QUnit.test( "core", function( assert ) {
assert.strictEqual( jQuery.parseHTML( "<div></div><span></span>" ).length,
2, "jQuery.parseHTML" );
-
- assert.deepEqual( jQuery.parseJSON( "{\"a\": 2}" ), { a: 2 }, "jQuery.parseJON" );
} );
QUnit.test( "data", function( assert ) {
@@ -189,10 +187,7 @@ QUnit.test( "manipulation", function( assert ) {
assert.strictEqual( elem1.text( "foo" ).text(), "foo", ".html getter/setter" );
assert.strictEqual(
-
- // Support: IE 8 only
- // IE 8 prints tag names in upper case.
- elem1.html( "<span/>" ).html().toLowerCase(),
+ elem1.html( "<span/>" ).html(),
"<span></span>",
".html getter/setter"
);
@@ -205,10 +200,7 @@ QUnit.test( "manipulation", function( assert ) {
child.before( "<b/>" );
assert.strictEqual(
-
- // Support: IE 8 only
- // IE 8 prints tag names in upper case.
- elem1.html().toLowerCase(),
+ elem1.html(),
"<div></div><b></b><span></span><a></a>",
".after/.before"
);
@@ -277,10 +269,7 @@ QUnit.test( "wrap", function( assert ) {
elem.find( "b" ).wrap( "<span>" );
assert.strictEqual(
-
- // Support: IE 8 only
- // IE 8 prints tag names in upper case.
- elem.html().toLowerCase(),
+ elem.html(),
"<a><span><b></b></span></a><a></a>",
".wrap"
);
@@ -288,10 +277,7 @@ QUnit.test( "wrap", function( assert ) {
elem.find( "span" ).wrapInner( "<em>" );
assert.strictEqual(
-
- // Support: IE 8 only
- // IE 8 prints tag names in upper case.
- elem.html().toLowerCase(),
+ elem.html(),
"<a><span><em><b></b></em></span></a><a></a>",
".wrapInner"
);
@@ -299,10 +285,7 @@ QUnit.test( "wrap", function( assert ) {
elem.find( "a" ).wrapAll( "<i>" );
assert.strictEqual(
-
- // Support: IE 8 only
- // IE 8 prints tag names in upper case.
- elem.html().toLowerCase(),
+ elem.html(),
"<i><a><span><em><b></b></em></span></a><a></a></i>",
".wrapAll"
);
diff --git a/test/unit/core.js b/test/unit/core.js
index 5f7d41d..f5083b4 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -1,4 +1,12 @@
-QUnit.module( "core", { teardown: moduleTeardown } );
+QUnit.module( "core", {
+ setup: function() {
+ this.sandbox = sinon.sandbox.create();
+ },
+ teardown: function() {
+ this.sandbox.restore();
+ return moduleTeardown.apply( this, arguments );
+ }
+} );
QUnit.test( "Basic requirements", function( assert ) {
assert.expect( 7 );
@@ -95,7 +103,7 @@ QUnit.test( "jQuery()", function( assert ) {
assert.equal( div.length, 4, "Correct number of elements generated for div hr code b" );
assert.equal( div.parent().length, 0, "Make sure that the generated HTML has no parent." );
- assert.equal( jQuery( [ 1,2,3 ] ).get( 1 ), 2, "Test passing an array to the factory" );
+ assert.equal( jQuery( [ 1, 2, 3 ] ).get( 1 ), 2, "Test passing an array to the factory" );
assert.equal( jQuery( document.body ).get( 0 ), jQuery( "body" ).get( 0 ), "Test passing an html node to the factory" );
@@ -189,27 +197,24 @@ QUnit.test( "globalEval execution after script injection (#7862)", function( ass
assert.ok( window.strictEvalTest - now < 500, "Code executed synchronously" );
} );
-// This is not run in AMD mode
-if ( jQuery.noConflict ) {
- QUnit.test( "noConflict", function( assert ) {
- assert.expect( 7 );
+QUnit.test( "noConflict", function( assert ) {
+ assert.expect( 7 );
- var $$ = jQuery;
+ var $$ = jQuery;
- assert.strictEqual( jQuery, jQuery.noConflict(), "noConflict returned the jQuery object" );
- assert.strictEqual( window[ "jQuery" ], $$, "Make sure jQuery wasn't touched." );
- assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
+ assert.strictEqual( jQuery, jQuery.noConflict(), "noConflict returned the jQuery object" );
+ assert.strictEqual( window[ "jQuery" ], $$, "Make sure jQuery wasn't touched." );
+ assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
- jQuery = $ = $$;
+ jQuery = $ = $$;
- assert.strictEqual( jQuery.noConflict( true ), $$, "noConflict returned the jQuery object" );
- assert.strictEqual( window[ "jQuery" ], originaljQuery, "Make sure jQuery was reverted." );
- assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
- assert.ok( $$().pushStack( [] ), "Make sure that jQuery still works." );
+ assert.strictEqual( jQuery.noConflict( true ), $$, "noConflict returned the jQuery object" );
+ assert.strictEqual( window[ "jQuery" ], originaljQuery, "Make sure jQuery was reverted." );
+ assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
+ assert.ok( $$().pushStack( [] ), "Make sure that jQuery still works." );
- window[ "jQuery" ] = jQuery = $$;
- } );
-}
+ window[ "jQuery" ] = jQuery = $$;
+} );
QUnit.test( "trim", function( assert ) {
assert.expect( 13 );
@@ -274,7 +279,7 @@ QUnit.test( "type", function( assert ) {
QUnit.test( "type for `Symbol`", function( assert ) {
// Prevent reference errors
- if( typeof Symbol !== "function" ) {
+ if ( typeof Symbol !== "function" ) {
assert.expect( 0 );
return;
}
@@ -283,16 +288,30 @@ QUnit.test( "type for `Symbol`", function( assert ) {
assert.equal( jQuery.type( Symbol() ), "symbol", "Symbol" );
assert.equal( jQuery.type( Object( Symbol() ) ), "symbol", "Symbol" );
-});
+} );
QUnit.asyncTest( "isPlainObject", function( assert ) {
- assert.expect( 15 );
- var pass, iframe, doc,
+ assert.expect( 23 );
+
+ var pass, iframe, doc, parentObj, childObj, deep,
fn = function() {};
// The use case that we want to match
assert.ok( jQuery.isPlainObject( {} ), "{}" );
+ assert.ok( jQuery.isPlainObject( new window.Object() ), "new Object" );
+ assert.ok( jQuery.isPlainObject( { constructor: fn } ),
+ "plain object with constructor property" );
+ assert.ok( jQuery.isPlainObject( { constructor: "foo" } ),
+ "plain object with primitive constructor property" );
+
+ parentObj = {};
+ childObj = Object.create( parentObj );
+ assert.ok( !jQuery.isPlainObject( childObj ), "Object.create({})" );
+ parentObj.foo = "bar";
+ assert.ok( !jQuery.isPlainObject( childObj ), "Object.create({...})" );
+ childObj.bar = "foo";
+ assert.ok( !jQuery.isPlainObject( childObj ), "extend(Object.create({...}), ...)" );
// Not objects shouldn't be matched
assert.ok( !jQuery.isPlainObject( "" ), "string" );
@@ -320,6 +339,14 @@ QUnit.asyncTest( "isPlainObject", function( assert ) {
// Again, instantiated objects shouldn't be matched
assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" );
+ // Instantiated objects with primitive constructors shouldn't be matched
+ fn.prototype.constructor = "foo";
+ assert.ok( !jQuery.isPlainObject( new fn() ), "new fn with primitive constructor" );
+
+ // Deep object
+ deep = { "foo": { "baz": true }, "foo2": document };
+ assert.ok( jQuery.isPlainObject( deep ), "Object with objects is still plain" );
+
// DOM Element
assert.ok( !jQuery.isPlainObject( document.createElement( "div" ) ), "DOM Element" );
@@ -353,7 +380,6 @@ QUnit.asyncTest( "isPlainObject", function( assert ) {
}
} );
-//
QUnit[ typeof Symbol === "function" ? "test" : "skip" ]( "isPlainObject(Symbol)", function( assert ) {
assert.expect( 2 );
@@ -361,6 +387,23 @@ QUnit[ typeof Symbol === "function" ? "test" : "skip" ]( "isPlainObject(Symbol)"
assert.equal( jQuery.isPlainObject( Object( Symbol() ) ), false, "Symbol inside an object" );
} );
+QUnit.test( "isPlainObject(localStorage)", function( assert ) {
+ assert.expect( 1 );
+
+ assert.equal( jQuery.isPlainObject( localStorage ), false );
+} );
+
+QUnit[ "assign" in Object ? "test" : "skip" ]( "isPlainObject(Object.assign(...))",
+ function( assert ) {
+ assert.expect( 1 );
+
+ var parentObj = { foo: "bar" };
+ var childObj = Object.assign( Object.create( parentObj ), { bar: "foo" } );
+
+ assert.ok( !jQuery.isPlainObject( childObj ), "isPlainObject(Object.assign(...))" );
+ }
+);
+
QUnit.test( "isFunction", function( assert ) {
assert.expect( 19 );
@@ -449,7 +492,7 @@ QUnit.test( "isFunction", function( assert ) {
} );
QUnit.test( "isNumeric", function( assert ) {
- assert.expect( 38 );
+ assert.expect( 43 );
var t = jQuery.isNumeric,
ToString = function( value ) {
@@ -464,9 +507,6 @@ QUnit.test( "isNumeric", function( assert ) {
assert.ok( t( -16 ), "Negative integer number" );
assert.ok( t( 0 ), "Zero integer number" );
assert.ok( t( 32 ), "Positive integer number" );
- assert.ok( t( "040" ), "Octal integer literal string" );
- assert.ok( t( "0xFF" ), "Hexadecimal integer literal string" );
- assert.ok( t( 0xFFF ), "Hexadecimal integer literal" );
assert.ok( t( "-1.6" ), "Negative floating point string" );
assert.ok( t( "4.536" ), "Positive floating point string" );
assert.ok( t( -2.6 ), "Negative floating point number" );
@@ -474,8 +514,28 @@ QUnit.test( "isNumeric", function( assert ) {
assert.ok( t( 1.5999999999999999 ), "Very precise floating point number" );
assert.ok( t( 8e5 ), "Exponential notation" );
assert.ok( t( "123e-2" ), "Exponential notation string" );
+ assert.ok( t( "040" ), "Legacy octal integer literal string" );
+ assert.ok( t( "0xFF" ), "Hexadecimal integer literal string (0x...)" );
+ assert.ok( t( "0Xba" ), "Hexadecimal integer literal string (0X...)" );
+ assert.ok( t( 0xFFF ), "Hexadecimal integer literal" );
+
+ if ( +"0b1" === 1 ) {
+ assert.ok( t( "0b111110" ), "Binary integer literal string (0b...)" );
+ assert.ok( t( "0B111110" ), "Binary integer literal string (0B...)" );
+ } else {
+ assert.ok( true, "Browser does not support binary integer literal (0b...)" );
+ assert.ok( true, "Browser does not support binary integer literal (0B...)" );
+ }
+
+ if ( +"0o1" === 1 ) {
+ assert.ok( t( "0o76" ), "Octal integer literal string (0o...)" );
+ assert.ok( t( "0O76" ), "Octal integer literal string (0O...)" );
+ } else {
+ assert.ok( true, "Browser does not support octal integer literal (0o...)" );
+ assert.ok( true, "Browser does not support octal integer literal (0O...)" );
+ }
- assert.equal( t( new ToString( "42" ) ), false, "Custom .toString returning number" );
+ assert.equal( t( new ToString( "42" ) ), false, "Only limited to strings and numbers" );
assert.equal( t( "" ), false, "Empty string" );
assert.equal( t( " " ), false, "Whitespace characters string" );
assert.equal( t( "\t\t" ), false, "Tab characters string" );
@@ -913,7 +973,7 @@ QUnit.test( "jQuery.map", function( assert ) {
assert.ok( !result, "empty NodeList treated like array" );
result = jQuery.map( Array( 4 ), function( v, k ) {
- return k % 2 ? k : [ k,k,k ];
+ return k % 2 ? k : [ k, k, k ];
} );
assert.equal( result.join( "" ), "00012223", "Array results flattened (#2616)" );
} );
@@ -1065,7 +1125,7 @@ QUnit.test( "jQuery.grep(Array-like)", function( assert ) {
[],
"Satisfying elements absent, Array-like object used, and grep explicitly uninverted"
);
-});
+} );
QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
assert.expect( 28 );
@@ -1133,7 +1193,6 @@ QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
ret = jQuery.extend( true, { "foo": 4 }, { "foo": new MyNumber( 5 ) } );
assert.ok( parseInt( ret.foo, 10 ) === 5, "Wrapped numbers copy correctly" );
- nullUndef;
nullUndef = jQuery.extend( {}, options, { "xnumber2": null } );
assert.ok( nullUndef[ "xnumber2" ] === null, "Check to make sure null values are copied" );
@@ -1183,19 +1242,19 @@ QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
QUnit.test( "jQuery.extend(Object, Object {created with \"defineProperties\"})", function( assert ) {
assert.expect( 2 );
- var definedObj = Object.defineProperties({}, {
+ var definedObj = Object.defineProperties( {}, {
"enumerableProp": {
- get: function () {
+ get: function() {
return true;
},
enumerable: true
},
"nonenumerableProp": {
- get: function () {
+ get: function() {
return true;
}
}
- }),
+ } ),
accessorObj = {};
jQuery.extend( accessorObj, definedObj );
@@ -1214,7 +1273,7 @@ QUnit.test( "jQuery.extend(true,{},{a:[], o:{}}); deep copy with array, followed
// If "copyIsArray" doesn't get reset to false, the check
// will evaluate true and enter the array copy block
// instead of the object copy block. Since the ternary in the
- // "copyIsArray" block will will evaluate to false
+ // "copyIsArray" block will evaluate to false
// (check if operating on an array with ), this will be
// replaced by an empty array.
object: {}
@@ -1253,7 +1312,7 @@ QUnit.test( "jQuery.each(Object,Function)", function( assert ) {
assert.deepEqual( seen, [ 1, 2 ], "Broken array iteration" );
seen = [];
- jQuery.each( { "a": 1, "b": 2,"c": 3 }, function( k, v ) {
+ jQuery.each( { "a": 1, "b": 2, "c": 3 }, function( k, v ) {
seen.push( v );
return false;
} );
@@ -1373,7 +1432,7 @@ QUnit.test( "jQuery.makeArray", function( assert ) {
assert.equal( ( function() { return jQuery.makeArray( arguments ); } )( 1, 2 ).join( "" ), "12", "Pass makeArray an arguments array" );
- assert.equal( jQuery.makeArray( [ 1,2,3 ] ).join( "" ), "123", "Pass makeArray a real array" );
+ assert.equal( jQuery.makeArray( [ 1, 2, 3 ] ).join( "" ), "123", "Pass makeArray a real array" );
assert.equal( jQuery.makeArray().length, 0, "Pass nothing to makeArray and expect an empty array" );
@@ -1515,6 +1574,15 @@ QUnit.test( "jQuery.parseHTML", function( assert ) {
assert.ok( jQuery.parseHTML( "<#if><tr><p>This is a test.</p></tr><#/if>" ) || true, "Garbage input should not cause error" );
} );
+QUnit.test( "jQuery.parseHTML(<a href>) - gh-2965", function( assert ) {
+ assert.expect( 1 );
+
+ var html = "<a href='test.html'></a>",
+ href = jQuery.parseHTML( html )[ 0 ].href;
+
+ assert.ok( /\/test\.html$/.test( href ), "href is not lost after parsing anchor" );
+} );
+
if ( jQuery.support.createHTMLDocument ) {
QUnit.asyncTest( "jQuery.parseHTML", function( assert ) {
assert.expect( 1 );
@@ -1531,93 +1599,6 @@ if ( jQuery.support.createHTMLDocument ) {
} );
}
-QUnit.test( "jQuery.parseJSON", function( assert ) {
- assert.expect( 20 );
-
- assert.strictEqual( jQuery.parseJSON( null ), null, "primitive null" );
- assert.strictEqual( jQuery.parseJSON( "0.88" ), 0.88, "Number" );
- assert.strictEqual(
- jQuery.parseJSON( "\" \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u007E \\u263a \"" ),
- " \" \\ / \b \f \n \r \t ~ \u263A ",
- "String escapes"
- );
- assert.deepEqual( jQuery.parseJSON( "{}" ), {}, "Empty object" );
- assert.deepEqual( jQuery.parseJSON( "{\"test\":1}" ), { "test": 1 }, "Plain object" );
- assert.deepEqual( jQuery.parseJSON( "[0]" ), [ 0 ], "Simple array" );
-
- assert.deepEqual(
- jQuery.parseJSON( "[ \"string\", -4.2, 2.7180e0, 3.14E-1, {}, [], true, false, null ]" ),
- [ "string", -4.2, 2.718, 0.314, {}, [], true, false, null ],
- "Array of all data types"
- );
- assert.deepEqual(
- jQuery.parseJSON( "{ \"string\": \"\", \"number\": 4.2e+1, \"object\": {}," +
- "\"array\": [[]], \"boolean\": [ true, false ], \"null\": null }" ),
- { string: "", number: 42, object: {}, array: [ [] ], "boolean": [ true, false ], "null": null },
- "Dictionary of all data types"
- );
-
- assert.deepEqual( jQuery.parseJSON( "\n{\"test\":1}\t" ), { "test": 1 },
- "Leading and trailing whitespace are ignored" );
-
- assert.throws( function() {
- jQuery.parseJSON();
- }, null, "Undefined raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "" );
- }, null, "Empty string raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "''" );
- }, null, "Single-quoted string raises an error" );
- /*
-
- // Broken on IE8
- assert.throws(function() {
- jQuery.parseJSON("\" \\a \"");
- }, null, "Invalid string escape raises an error" );
-
- // Broken on IE8, Safari 5.1 Windows
- assert.throws(function() {
- jQuery.parseJSON("\"\t\"");
- }, null, "Unescaped control character raises an error" );
-
- // Broken on IE8
- assert.throws(function() {
- jQuery.parseJSON(".123");
- }, null, "Number with no integer component raises an error" );
-
- */
- assert.throws( function() {
- var result = jQuery.parseJSON( "0101" );
-
- // Support: IE9+
- // Ensure base-10 interpretation on browsers that erroneously accept leading-zero numbers
- if ( result === 101 ) {
- throw new Error( "close enough" );
- }
- }, null, "Leading-zero number raises an error or is parsed as decimal" );
- assert.throws( function() {
- jQuery.parseJSON( "{a:1}" );
- }, null, "Unquoted property raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "{'a':1}" );
- }, null, "Single-quoted property raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "[,]" );
- }, null, "Array element elision raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "{},[]" );
- }, null, "Comma expression raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "[]\n,{}" );
- }, null, "Newline-containing comma expression raises an error" );
- assert.throws( function() {
- jQuery.parseJSON( "\"\"\n\"\"" );
- }, null, "Automatic semicolon insertion raises an error" );
-
- assert.strictEqual( jQuery.parseJSON( [ 0 ] ), 0, "Input cast to string" );
-} );
-
QUnit.test( "jQuery.parseXML", function( assert ) {
assert.expect( 8 );
@@ -1671,14 +1652,14 @@ QUnit.test( "jQuery.camelCase()", function( assert ) {
} );
} );
-testIframeWithCallback(
+testIframe(
"Conditional compilation compatibility (#13274)",
"core/cc_on.html",
- function( cc_on, errors, $, assert ) {
+ function( assert, jQuery, window, document, cc_on, errors ) {
assert.expect( 3 );
assert.ok( true, "JScript conditional compilation " + ( cc_on ? "supported" : "not supported" ) );
assert.deepEqual( errors, [], "No errors" );
- assert.ok( $(), "jQuery executes" );
+ assert.ok( jQuery(), "jQuery executes" );
}
);
@@ -1686,36 +1667,35 @@ testIframeWithCallback(
// This makes this test fail but it doesn't seem to cause any real-life problems so blacklisting
// this test there is preferred to complicating the hard-to-test core/ready code further.
if ( !/iphone os 7_/i.test( navigator.userAgent ) ) {
- testIframeWithCallback(
+ testIframe(
"document ready when jQuery loaded asynchronously (#13655)",
"core/dynamic_ready.html",
- function( ready, assert ) {
+ function( assert, jQuery, window, document, ready ) {
assert.expect( 1 );
assert.equal( true, ready, "document ready correctly fired when jQuery is loaded after DOMContentLoaded" );
}
);
}
-testIframeWithCallback(
+testIframe(
"Tolerating alias-masked DOM properties (#14074)",
"core/aliased.html",
- function( errors, assert ) {
+ function( assert, jQuery, window, document, errors ) {
assert.expect( 1 );
assert.deepEqual( errors, [], "jQuery loaded" );
}
);
-testIframeWithCallback(
+testIframe(
"Don't call window.onready (#14802)",
"core/onready.html",
- function( error, assert ) {
+ function( assert, jQuery, window, document, error ) {
assert.expect( 1 );
assert.equal( error, false, "no call to user-defined onready" );
}
);
QUnit.test( "Iterability of jQuery objects (gh-1693)", function( assert ) {
- /* jshint unused: false */
assert.expect( 1 );
var i, elem, result;
@@ -1733,3 +1713,45 @@ QUnit.test( "Iterability of jQuery objects (gh-1693)", function( assert ) {
assert.ok( true, "The browser doesn't support Symbols" );
}
} );
+
+QUnit[ jQuery.Deferred ? "test" : "skip" ]( "jQuery.readyException (original)", function( assert ) {
+ assert.expect( 1 );
+
+ var message;
+
+ this.sandbox.stub( window, "setTimeout", function( fn ) {
+ try {
+ fn();
+ } catch ( error ) {
+ message = error.message;
+ }
+ } );
+
+ jQuery( function() {
+ throw new Error( "Error in jQuery ready" );
+ } );
+ assert.strictEqual(
+ message,
+ "Error in jQuery ready",
+ "The error should have been thrown in a timeout"
+ );
+} );
+
+QUnit[ jQuery.Deferred ? "test" : "skip" ]( "jQuery.readyException (custom)", function( assert ) {
+ assert.expect( 1 );
+
+ var done = assert.async();
+
+ this.sandbox.stub( jQuery, "readyException", function( error ) {
+ assert.strictEqual(
+ error.message,
+ "Error in jQuery ready",
+ "The custom jQuery.readyException should have been called"
+ );
+ done();
+ } );
+
+ jQuery( function() {
+ throw new Error( "Error in jQuery ready" );
+ } );
+} );
diff --git a/test/unit/css.js b/test/unit/css.js
index 4ecd08a..2f529b6 100644
--- a/test/unit/css.js
+++ b/test/unit/css.js
@@ -58,9 +58,9 @@ QUnit.test( "css(String|Hash)", function( assert ) {
jQuery( "#foo" ).css( { "opacity": "" } );
assert.equal( jQuery( "#foo" ).css( "opacity" ), "1", "Assert opacity is 1 when set to an empty String" );
- assert.equal( jQuery( "#empty" ).css( "opacity" ), "0", "Assert opacity is accessible via filter property set in stylesheet in IE" );
+ assert.equal( jQuery( "#empty" ).css( "opacity" ), "0", "Assert opacity is accessible" );
jQuery( "#empty" ).css( { "opacity": "1" } );
- assert.equal( jQuery( "#empty" ).css( "opacity" ), "1", "Assert opacity is taken from style attribute when set vs stylesheet in IE with filters" );
+ assert.equal( jQuery( "#empty" ).css( "opacity" ), "1", "Assert opacity is taken from style attribute when set" );
div = jQuery( "#nothiddendiv" );
child = jQuery( "#nothiddendivchild" );
@@ -141,7 +141,7 @@ QUnit.test( "css() explicit and relative values", function( assert ) {
$elem.css( "width", "+=9" );
assert.equal( $elem.css( "width" ), "10px", "'+=9' on width (params)" );
- $elem.css( "width", "-=9" ) ;
+ $elem.css( "width", "-=9" );
assert.equal( $elem.css( "width" ), "1px", "'-=9' on width (params)" );
$elem.css( "width", "+=9px" );
@@ -354,8 +354,8 @@ QUnit.test( "css(String, Function)", function( assert ) {
sizes = [ "10px", "20px", "30px" ];
jQuery( "<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
- "<div class='cssFunction'></div></div>" )
+ "<div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div></div>" )
.appendTo( "body" );
index = 0;
@@ -385,8 +385,8 @@ QUnit.test( "css(String, Function) with incoming value", function( assert ) {
sizes = [ "10px", "20px", "30px" ];
jQuery( "<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
- "<div class='cssFunction'></div></div>" )
+ "<div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div></div>" )
.appendTo( "body" );
index = 0;
@@ -416,8 +416,8 @@ QUnit.test( "css(Object) where values are Functions", function( assert ) {
sizes = [ "10px", "20px", "30px" ];
jQuery( "<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
- "<div class='cssFunction'></div></div>" )
+ "<div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div></div>" )
.appendTo( "body" );
index = 0;
@@ -447,8 +447,8 @@ QUnit.test( "css(Object) where values are Functions with incoming values", funct
sizes = [ "10px", "20px", "30px" ];
jQuery( "<div id='cssFunctionTest'><div class='cssFunction'></div>" +
- "<div class='cssFunction'></div>" +
- "<div class='cssFunction'></div></div>" )
+ "<div class='cssFunction'></div>" +
+ "<div class='cssFunction'></div></div>" )
.appendTo( "body" );
index = 0;
@@ -478,7 +478,7 @@ QUnit.test( "show()", function( assert ) {
assert.expect( 18 );
- var hiddendiv, div, pass, old, test;
+ var hiddendiv, div, pass, test;
hiddendiv = jQuery( "div.hidden" );
assert.equal( jQuery.css( hiddendiv[ 0 ], "display" ), "none", "hiddendiv is display: none" );
@@ -504,13 +504,9 @@ QUnit.test( "show()", function( assert ) {
"<div id='show-tests'>" +
"<div><p><a href='#'></a></p><code></code><pre></pre><span></span></div>" +
"<table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table>" +
- "<ul><li></li></ul></div>" +
- "<table id='test-table'></table>"
+ "<ul><li></li></ul></div>"
).appendTo( "#qunit-fixture" ).find( "*" ).css( "display", "none" );
- old = jQuery( "#test-table" ).show().css( "display" ) !== "table";
- jQuery( "#test-table" ).remove();
-
test = {
"div": "block",
"p": "block",
@@ -518,14 +514,14 @@ QUnit.test( "show()", function( assert ) {
"code": "inline",
"pre": "block",
"span": "inline",
- "table": old ? "block" : "table",
- "thead": old ? "block" : "table-header-group",
- "tbody": old ? "block" : "table-row-group",
- "tr": old ? "block" : "table-row",
- "th": old ? "block" : "table-cell",
- "td": old ? "block" : "table-cell",
+ "table": "table",
+ "thead": "table-header-group",
+ "tbody": "table-row-group",
+ "tr": "table-row",
+ "th": "table-cell",
+ "td": "table-cell",
"ul": "block",
- "li": old ? "block" : "list-item"
+ "li": "list-item"
};
jQuery.each( test, function( selector, expected ) {
@@ -930,6 +926,30 @@ QUnit[ jQuery.find.compile && jQuery.fn.toggle ? "test" : "skip" ]( "toggle()",
jQuery.fn.hide = oldHide;
} );
+QUnit[ jQuery.find.compile && jQuery.fn.toggle ? "test" : "skip" ]( "detached toggle()", function( assert ) {
+ assert.expect( 6 );
+ var detached = jQuery( "<p><a/><p>" ).find( "*" ).addBack(),
+ hiddenDetached = jQuery( "<p><a/></p>" ).find( "*" ).addBack().css( "display", "none" ),
+ cascadeHiddenDetached = jQuery( "<p><a/></p>" ).find( "*" ).addBack().addClass( "hidden" );
+
+ detached.toggle();
+ detached.appendTo( "#qunit-fixture" );
+ assert.equal( detached[ 0 ].style.display, "none", "detached element" );
+ assert.equal( detached[ 1 ].style.display, "none", "element in detached tree" );
+
+ hiddenDetached.toggle();
+ hiddenDetached.appendTo( "#qunit-fixture" );
+ assert.equal( hiddenDetached[ 0 ].style.display, "", "detached, hidden element" );
+ assert.equal( hiddenDetached[ 1 ].style.display, "", "hidden element in detached tree" );
+
+ cascadeHiddenDetached.toggle();
+ cascadeHiddenDetached.appendTo( "#qunit-fixture" );
+ assert.equal( cascadeHiddenDetached[ 0 ].style.display, "none",
+ "detached, cascade-hidden element" );
+ assert.equal( cascadeHiddenDetached[ 1 ].style.display, "none",
+ "cascade-hidden element in detached tree" );
+} );
+
QUnit.test( "jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function( assert ) {
assert.expect( 4 );
@@ -968,18 +988,18 @@ QUnit.test( "computed margins (trac-3333; gh-2237)", function( assert ) {
assert.equal( $div.css( "marginRight" ), "0px",
"marginRight correctly calculated with a width and display block" );
- $div.css({
+ $div.css( {
position: "absolute",
top: 0,
left: 0,
width: "100px"
- });
- $child.css({
+ } );
+ $child.css( {
width: "50px",
margin: "auto"
- });
+ } );
assert.equal( $child.css( "marginLeft" ), "25px", "auto margins are computed to pixels" );
-});
+} );
QUnit.test( "box model properties incorrectly returning % instead of px, see #10639 and #12088", function( assert ) {
assert.expect( 2 );
@@ -1037,6 +1057,16 @@ QUnit.test( "can't get css for disconnected in IE<9, see #10254 and #8388", func
assert.equal( div.css( "top" ), "10px", "can't get top in IE<9, see #8388" );
} );
+QUnit.test( "Ensure styles are retrieving from parsed html on document fragments", function( assert ) {
+ assert.expect( 1 );
+
+ var $span = jQuery(
+ jQuery.parseHTML( "<span style=\"font-family: Cuprum,sans-serif; font-size: 14px; color: #999999;\">some text</span>" )
+ );
+
+ assert.equal( $span.css( "font-size" ), "14px", "Font-size retrievable on parsed HTML node" );
+} );
+
QUnit.test( "can't get background-position in IE<9, see #10796", function( assert ) {
var div = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ),
units = [
@@ -1078,12 +1108,7 @@ QUnit.test( "Do not append px (#9548, #12990, #2792)", function( assert ) {
$div.css( "fill-opacity", 1 );
- // Support: Android 2.3 (no support for fill-opacity)
- if ( $div.css( "fill-opacity" ) !== undefined ) {
- assert.equal( $div.css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" );
- } else {
- assert.ok( true, "No support for fill-opacity CSS property" );
- }
+ assert.equal( $div.css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" );
$div.css( "column-count", 1 );
if ( $div.css( "column-count" ) !== undefined ) {
@@ -1105,8 +1130,7 @@ QUnit.test( "Do not append px (#9548, #12990, #2792)", function( assert ) {
QUnit.test( "css('width') and css('height') should respect box-sizing, see #11004", function( assert ) {
assert.expect( 4 );
- // Support: Android 2.3 (-webkit-box-sizing).
- var el_dis = jQuery( "<div style='width:300px;height:300px;margin:2px;padding:2px;-webkit-box-sizing:border-box;box-sizing:border-box;'>test</div>" ),
+ var el_dis = jQuery( "<div style='width:300px;height:300px;margin:2px;padding:2px;box-sizing:border-box;'>test</div>" ),
el = el_dis.clone().appendTo( "#qunit-fixture" );
assert.equal( el.css( "width" ), el.css( "width", el.css( "width" ) ).css( "width" ), "css('width') is not respecting box-sizing, see #11004" );
@@ -1115,10 +1139,10 @@ QUnit.test( "css('width') and css('height') should respect box-sizing, see #1100
assert.equal( el_dis.css( "height" ), el_dis.css( "height", el_dis.css( "height" ) ).css( "height" ), "css('height') is not respecting box-sizing for disconnected element, see #11004" );
} );
-testIframeWithCallback(
+testIframe(
"css('width') should work correctly before document ready (#14084)",
"css/cssWidthBeforeDocReady.html",
- function( cssWidthBeforeDocReady, assert ) {
+ function( assert, jQuery, window, document, cssWidthBeforeDocReady ) {
assert.expect( 1 );
assert.strictEqual( cssWidthBeforeDocReady, "100px", "elem.css('width') works correctly before document ready" );
}
@@ -1179,7 +1203,8 @@ QUnit.test( "certain css values of 'normal' should be convertable to a number, s
assert.equal( typeof el.css( "fontWeight" ), "string", ".css() returns a string" );
} );
-// only run this test in IE9
+// Support: IE 9 only
+// Only run this test in IE9
if ( document.documentMode === 9 ) {
QUnit.test( ".css('filter') returns a string in IE9, see #12537", function( assert ) {
assert.expect( 1 );
@@ -1229,23 +1254,21 @@ QUnit.test( "cssHooks - expand", function( assert ) {
} );
QUnit.test( "css opacity consistency across browsers (#12685)", function( assert ) {
- assert.expect( 4 );
+ assert.expect( 3 );
var el,
fixture = jQuery( "#qunit-fixture" );
// Append style element
- jQuery( "<style>.opacityWithSpaces_t12685 { opacity: 0.1; filter: alpha(opacity = 10); } .opacityNoSpaces_t12685 { opacity: 0.2; filter: alpha(opacity=20); }</style>" ).appendTo( fixture );
+ jQuery( "<style>.opacity_t12685 { opacity: 0.1; }</style>" ).appendTo( fixture );
- el = jQuery( "<div class='opacityWithSpaces_t12685'></div>" ).appendTo( fixture );
+ el = jQuery( "<div class='opacity_t12685'></div>" ).appendTo( fixture );
- assert.equal( Math.round( el.css( "opacity" ) * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" );
- el.removeClass( "opacityWithSpaces_t12685" ).addClass( "opacityNoSpaces_t12685" );
- assert.equal( Math.round( el.css( "opacity" ) * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" );
+ assert.equal( Math.round( el.css( "opacity" ) * 100 ), 10, "opacity from style sheet" );
el.css( "opacity", 0.3 );
assert.equal( Math.round( el.css( "opacity" ) * 100 ), 30, "override opacity" );
el.css( "opacity", "" );
- assert.equal( Math.round( el.css( "opacity" ) * 100 ), 20, "remove opacity override" );
+ assert.equal( Math.round( el.css( "opacity" ) * 100 ), 10, "remove opacity override" );
} );
QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", function( assert ) {
@@ -1286,7 +1309,7 @@ QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", fu
assert.t( "Is Visible", "#qunit-fixture div:visible:lt(2)", [ "foo", "nothiddendiv" ] );
assert.t( "Is Not Hidden", "#qunit-fixture:hidden", [] );
- assert.t( "Is Hidden", "#form input:hidden", [ "hidden1","hidden2" ] );
+ assert.t( "Is Hidden", "#form input:hidden", [ "hidden1", "hidden2" ] );
$a = jQuery( "<a href='#'><h1>Header</h1></a>" ).appendTo( "#qunit-fixture" );
assert.ok( $a.is( ":visible" ), "Anchor tag with flow content is visible (gh-2227)" );
@@ -1299,7 +1322,16 @@ QUnit.test( "Keep the last style if the new one isn't recognized by the browser
el = jQuery( "<div></div>" ).css( "position", "absolute" ).css( "position", "fake value" );
assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting an unrecognized value" );
el = jQuery( "<div></div>" ).css( "position", "absolute" ).css( "position", " " );
- assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting to a space" );
+
+ // Support: Edge 14
+ // Edge collapses whitespace-only values when setting a style property and
+ // there is no easy way for us to work around it. Just skip the test there
+ // and hope for the better future.
+ if ( /edge\//i.test( navigator.userAgent ) ) {
+ assert.ok( true, "Skipped (Edge 14 handles whitespace-only values incorrectly)" );
+ } else {
+ assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting to a space" );
+ }
} );
QUnit.test( "Reset the style if set to an empty string", function( assert ) {
@@ -1322,7 +1354,7 @@ QUnit.test(
name: "backgroundAttachment",
value: [ "fixed" ],
expected: [ "scroll" ]
- },{
+ }, {
name: "backgroundColor",
value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ],
expected: [ "transparent" ]
@@ -1399,7 +1431,7 @@ QUnit.test(
}
);
-// Support: IE < 11
+// Support: IE <=10 only
// We have to jump through the hoops here in order to test work with "order" CSS property,
// that some browsers do not support. This test is not, strictly speaking, correct,
// but it's the best that we can do.
diff --git a/test/unit/data.js b/test/unit/data.js
index 31c6a61..0eb1d51 100644
--- a/test/unit/data.js
+++ b/test/unit/data.js
@@ -277,7 +277,7 @@ QUnit.test( "data-* attributes", function( assert ) {
var prop, i, l, metadata, elem,
obj, obj2, check, num, num2,
- parseJSON = jQuery.parseJSON,
+ parseJSON = JSON.parse,
div = jQuery( "<div>" ),
child = jQuery( "<div data-myobj='old data' data-ignored=\"DOM\" data-other='test' data-foo-42='boosh'></div>" ),
dummy = jQuery( "<div data-myobj='old data' data-ignored=\"DOM\" data-other='test' data-foo-42='boosh'></div>" );
@@ -336,7 +336,7 @@ QUnit.test( "data-* attributes", function( assert ) {
// attribute parsing
i = 0;
- jQuery.parseJSON = function() {
+ JSON.parse = function() {
i++;
return parseJSON.apply( this, arguments );
};
@@ -389,7 +389,7 @@ QUnit.test( "data-* attributes", function( assert ) {
assert.strictEqual( child.data( "string" ), "test", "Typical string read from attribute" );
assert.equal( i, 2, "Correct number of JSON parse attempts when reading from attributes" );
- jQuery.parseJSON = parseJSON;
+ JSON.parse = parseJSON;
child.remove();
// tests from metadata plugin
@@ -409,7 +409,7 @@ QUnit.test( "data-* attributes", function( assert ) {
break;
case 3:
assert.equal( jQuery( elem ).data( "number" ), true, "Check number property" );
- assert.deepEqual( jQuery( elem ).data( "stuff" ), [ 2,8 ], "Check stuff property" );
+ assert.deepEqual( jQuery( elem ).data( "stuff" ), [ 2, 8 ], "Check stuff property" );
break;
default:
assert.ok( false, [ "Assertion failed on index ", index, ", with data" ].join( "" ) );
@@ -857,10 +857,10 @@ QUnit.test( "Check proper data removal of non-element descendants nodes (#8335)"
assert.ok( !text.data( "test" ), "Be sure data is not stored in non-element" );
} );
-testIframeWithCallback(
+testIframe(
"enumerate data attrs on body (#14894)",
"data/dataAttrs.html",
- function( result, assert ) {
+ function( assert, jQuery, window, document, result ) {
assert.expect( 1 );
assert.equal( result, "ok", "enumeration of data- attrs on body" );
}
@@ -881,13 +881,13 @@ QUnit.test( "Check that the expando is removed when there's no more data", funct
assert.strictEqual( div[ 0 ][ key ], undefined, "Expando was not removed when there was no more data" );
}
}
-});
+} );
QUnit.test( "Check that the expando is removed when there's no more data on non-nodes", function( assert ) {
assert.expect( 1 );
var key,
- obj = jQuery( {key: 42} );
+ obj = jQuery( { key: 42 } );
obj.data( "some", "data" );
assert.equal( obj.data( "some" ), "data", "Data is added" );
obj.removeData( "some" );
diff --git a/test/unit/deferred.js b/test/unit/deferred.js
index d65ce34..32f3256 100644
--- a/test/unit/deferred.js
+++ b/test/unit/deferred.js
@@ -16,20 +16,21 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
assert.ok( jQuery.isFunction( defer.pipe ), "defer.pipe is a function" );
- createDeferred().resolve().done( function() {
+ defer.resolve().done( function() {
assert.ok( true, "Success on resolve" );
- assert.strictEqual( this.state(), "resolved", "Deferred is resolved (state)" );
+ assert.strictEqual( defer.state(), "resolved", "Deferred is resolved (state)" );
} ).fail( function() {
assert.ok( false, "Error on resolve" );
} ).always( function() {
assert.ok( true, "Always callback on resolve" );
} );
- createDeferred().reject().done( function() {
+ defer = createDeferred();
+ defer.reject().done( function() {
assert.ok( false, "Success on reject" );
} ).fail( function() {
assert.ok( true, "Error on reject" );
- assert.strictEqual( this.state(), "rejected", "Deferred is rejected (state)" );
+ assert.strictEqual( defer.state(), "rejected", "Deferred is rejected (state)" );
} ).always( function() {
assert.ok( true, "Always callback on reject" );
} );
@@ -405,21 +406,31 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - deferred (progress)", function(
QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
- assert.expect( 7 );
+ assert.expect( 11 );
var defer, piped, defer2, piped2,
- context = {},
- done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
+ context = { custom: true },
+ done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
jQuery.Deferred().resolveWith( context, [ 2 ] ).then( function( value ) {
+ assert.strictEqual( this, context, "custom context received by .then handler" );
return value * 3;
} ).done( function( value ) {
- assert.notStrictEqual( this, context, "custom context not propagated through .then" );
+ assert.notStrictEqual( this, context,
+ "custom context not propagated through .then handler" );
assert.strictEqual( value, 6, "proper value received" );
done.pop().call();
} );
+ jQuery.Deferred().resolveWith( context, [ 2 ] ).then().done( function( value ) {
+ assert.strictEqual( this, context,
+ "custom context propagated through .then without handler" );
+ assert.strictEqual( value, 2, "proper value received" );
+ done.pop().call();
+ } );
+
jQuery.Deferred().resolve().then( function() {
+ assert.strictEqual( this, window, "default context in .then handler" );
return jQuery.Deferred().resolveWith( context );
} ).done( function() {
assert.strictEqual( this, context,
@@ -435,8 +446,7 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
defer.resolve( 2 );
piped.done( function( value ) {
- assert.strictEqual( this, piped,
- "default context gets updated to latest promise in the chain" );
+ assert.strictEqual( this, window, ".then handler does not introduce context" );
assert.strictEqual( value, 6, "proper value received" );
done.pop().call();
} );
@@ -447,8 +457,7 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
defer2.resolve( 2 );
piped2.done( function( value ) {
- assert.strictEqual( this, piped2,
- "default context updated to latest promise in the chain (without passing function)" );
+ assert.strictEqual( this, window, ".then without handler does not introduce context" );
assert.strictEqual( value, 2, "proper value received (without passing function)" );
done.pop().call();
} );
@@ -456,21 +465,31 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
- assert.expect( 7 );
+ assert.expect( 11 );
var defer, piped, defer2, piped2,
- context = {},
- done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
+ context = { custom: true },
+ done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe( function( value ) {
+ assert.strictEqual( this, context, "custom context received by .pipe handler" );
return value * 3;
} ).done( function( value ) {
- assert.strictEqual( this, context, "[PIPE ONLY] custom context correctly propagated" );
+ assert.strictEqual( this, context,
+ "[PIPE ONLY] custom context propagated through .pipe handler" );
assert.strictEqual( value, 6, "proper value received" );
done.pop().call();
} );
+ jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe().done( function( value ) {
+ assert.strictEqual( this, context,
+ "[PIPE ONLY] custom context propagated through .pipe without handler" );
+ assert.strictEqual( value, 2, "proper value received" );
+ done.pop().call();
+ } );
+
jQuery.Deferred().resolve().pipe( function() {
+ assert.strictEqual( this, window, "default context in .pipe handler" );
return jQuery.Deferred().resolveWith( context );
} ).done( function() {
assert.strictEqual( this, context,
@@ -486,8 +505,7 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
defer.resolve( 2 );
piped.done( function( value ) {
- assert.strictEqual( this, piped,
- "default context gets updated to latest promise in the chain" );
+ assert.strictEqual( this, window, ".pipe handler does not introduce context" );
assert.strictEqual( value, 6, "proper value received" );
done.pop().call();
} );
@@ -498,8 +516,7 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
defer2.resolve( 2 );
piped2.done( function( value ) {
- assert.strictEqual( this, piped2,
- "default context updated to latest promise in the chain (without passing function)" );
+ assert.strictEqual( this, window, ".pipe without handler does not introduce context" );
assert.strictEqual( value, 2, "proper value received (without passing function)" );
done.pop().call();
} );
@@ -525,27 +542,49 @@ QUnit.test( "jQuery.Deferred.then - spec compatibility", function( assert ) {
} catch ( _ ) {}
} );
+// Test fails in IE9 but is skipped there because console is not active
QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook", function( assert ) {
- assert.expect( 1 );
+ assert.expect( 2 );
var done = assert.async(),
defer = jQuery.Deferred(),
oldWarn = window.console.warn;
- window.console.warn = function( msg ) {
- assert.ok( /barf/.test( msg ), "Message: " + msg );
+ window.console.warn = function() {
+
+ // Support: Chrome <=41 only
+ // Some Chrome versions newer than 30 but older than 42 display the "undefined is
+ // not a function" error, not mentioning the function name. This has been fixed
+ // in Chrome 42. Relax this test there.
+ // This affects our Android 5.0 & Yandex.Browser testing.
+ var msg = Array.prototype.join.call( arguments, " " ),
+ oldChromium = false;
+ if ( /chrome/i.test( navigator.userAgent ) ) {
+ oldChromium = parseInt(
+ navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ], 10 ) < 42;
+ }
+ if ( oldChromium ) {
+ assert.ok( /(?:barf|undefined)/.test( msg ), "Message (weak assertion): " + msg );
+ } else {
+ assert.ok( /barf/.test( msg ), "Message: " + msg );
+ }
};
jQuery.when(
defer.then( function() {
+
// Should get an error
jQuery.barf();
} ).then( null, jQuery.noop ),
+
defer.then( function() {
+
// Should NOT get an error
throw new Error( "Make me a sandwich" );
} ).then( null, jQuery.noop )
- ).then( function( ) {
+ ).then( function barf( ) {
+ jQuery.thisDiesToo();
+ } ).then( null, function( ) {
window.console.warn = oldWarn;
done();
} );
@@ -553,6 +592,7 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook", func
defer.resolve();
} );
+// Test fails in IE9 but is skipped there because console is not active
QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook with stack hooks", function( assert ) {
assert.expect( 2 );
@@ -562,6 +602,7 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook with s
oldWarn = window.console.warn;
jQuery.Deferred.getStackHook = function() {
+
// Default exceptionHook assumes the stack is in a form console.warn can log,
// but a custom getStackHook+exceptionHook pair could save a raw form and
// format it to a string only when an exception actually occurs.
@@ -569,9 +610,26 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook with s
return "NO STACK FOR YOU";
};
- window.console.warn = function( msg, stack ) {
- assert.ok( /cough_up_hairball/.test( msg ), "Function mentioned: " + msg );
- assert.ok( /NO STACK FOR YOU/.test( stack ), "Stack trace included: " + stack );
+ window.console.warn = function() {
+
+ // Support: Chrome <=41 only
+ // Some Chrome versions newer than 30 but older than 42 display the "undefined is
+ // not a function" error, not mentioning the function name. This has been fixed
+ // in Chrome 42. Relax this test there.
+ // This affects our Android 5.0 & Yandex.Browser testing.
+ var msg = Array.prototype.join.call( arguments, " " ),
+ oldChromium = false;
+ if ( /chrome/i.test( navigator.userAgent ) ) {
+ oldChromium = parseInt(
+ navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ], 10 ) < 42;
+ }
+ if ( oldChromium ) {
+ assert.ok( /(?:cough_up_hairball|undefined)/.test( msg ),
+ "Function mentioned (weak assertion): " + msg );
+ } else {
+ assert.ok( /cough_up_hairball/.test( msg ), "Function mentioned: " + msg );
+ }
+ assert.ok( /NO STACK FOR YOU/.test( msg ), "Stack trace included: " + msg );
};
defer.then( function() {
jQuery.cough_up_hairball();
@@ -710,11 +768,60 @@ QUnit.test( "jQuery.Deferred - notify and resolve", function( assert ) {
} );
} );
-QUnit.test( "jQuery.when", function( assert ) {
+QUnit.test( "jQuery.Deferred - resolved to a notifying deferred", function( assert ) {
+
+ assert.expect( 2 );
+
+ var deferred = jQuery.Deferred(),
+ done = assert.async( 2 );
+
+ deferred.resolve( jQuery.Deferred( function( notifyingDeferred ) {
+ notifyingDeferred.notify( "foo", "bar" );
+ notifyingDeferred.resolve( "baz", "quux" );
+ } ) );
+
+ // Apply an empty then to force thenable unwrapping.
+ // See https://github.com/jquery/jquery/issues/3000 for more info.
+ deferred.then().then( function() {
+ assert.deepEqual(
+ [].slice.call( arguments ),
+ [ "baz", "quux" ],
+ "The fulfilled handler receives proper params"
+ );
+ done();
+ }, null, function() {
+ assert.deepEqual(
+ [].slice.call( arguments ),
+ [ "foo", "bar" ],
+ "The progress handler receives proper params"
+ );
+ done();
+ } );
+} );
+
+QUnit.test( "jQuery.when(nonThenable) - like Promise.resolve", function( assert ) {
+ "use strict";
+
+ assert.expect( 44 );
+
+ var
- assert.expect( 37 );
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ defaultContext = ( function getDefaultContext() { return this; } ).call(),
+
+ done = assert.async( 20 );
+
+ jQuery.when()
+ .done( function( resolveValue ) {
+ assert.strictEqual( resolveValue, undefined, "Resolved .done with no arguments" );
+ assert.strictEqual( this, defaultContext, "Default .done context with no arguments" );
+ } )
+ .then( function( resolveValue ) {
+ assert.strictEqual( resolveValue, undefined, "Resolved .then with no arguments" );
+ assert.strictEqual( this, defaultContext, "Default .then context with no arguments" );
+ } );
- // Some other objects
jQuery.each( {
"an empty string": "",
"a non-empty string": "some string",
@@ -727,51 +834,145 @@ QUnit.test( "jQuery.when", function( assert ) {
"a plain object": {},
"an array": [ 1, 2, 3 ]
}, function( message, value ) {
- assert.ok(
- jQuery.isFunction(
- jQuery.when( value ).done( function( resolveValue ) {
- assert.strictEqual( this, window, "Context is the global object with " + message );
- assert.strictEqual( resolveValue, value, "Test the promise was resolved with " + message );
- } ).promise
- ),
- "Test " + message + " triggers the creation of a new Promise"
- );
+ var code = "jQuery.when( " + message + " )",
+ onFulfilled = function( method ) {
+ var call = code + "." + method;
+ return function( resolveValue ) {
+ assert.strictEqual( resolveValue, value, call + " resolve" );
+ assert.strictEqual( this, defaultContext, call + " context" );
+ done();
+ };
+ },
+ onRejected = function( method ) {
+ var call = code + "." + method;
+ return function() {
+ assert.ok( false, call + " reject" );
+ done();
+ };
+ };
+
+ jQuery.when( value )
+ .done( onFulfilled( "done" ) )
+ .fail( onRejected( "done" ) )
+ .then( onFulfilled( "then" ), onRejected( "then" ) );
} );
+} );
- assert.ok(
- jQuery.isFunction(
- jQuery.when().done( function( resolveValue ) {
- assert.strictEqual( this, window, "Test the promise was resolved with window as its context" );
- assert.strictEqual( resolveValue, undefined, "Test the promise was resolved with no parameter" );
- } ).promise
- ),
- "Test calling when with no parameter triggers the creation of a new Promise"
- );
+QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
+ "use strict";
+
+ var CASES = 16,
+ slice = [].slice,
+ sentinel = { context: "explicit" },
+ eventuallyFulfilled = jQuery.Deferred().notify( true ),
+ eventuallyRejected = jQuery.Deferred().notify( true ),
+ secondaryFulfilled = jQuery.Deferred().resolve( eventuallyFulfilled ),
+ secondaryRejected = jQuery.Deferred().resolve( eventuallyRejected ),
+ inputs = {
+ promise: Promise.resolve( true ),
+ rejectedPromise: Promise.reject( false ),
+ deferred: jQuery.Deferred().resolve( true ),
+ eventuallyFulfilled: eventuallyFulfilled,
+ secondaryFulfilled: secondaryFulfilled,
+ eventuallySecondaryFulfilled: jQuery.Deferred().notify( true ),
+ multiDeferred: jQuery.Deferred().resolve( "foo", "bar" ),
+ deferredWith: jQuery.Deferred().resolveWith( sentinel, [ true ] ),
+ multiDeferredWith: jQuery.Deferred().resolveWith( sentinel, [ "foo", "bar" ] ),
+ rejectedDeferred: jQuery.Deferred().reject( false ),
+ eventuallyRejected: eventuallyRejected,
+ secondaryRejected: secondaryRejected,
+ eventuallySecondaryRejected: jQuery.Deferred().notify( true ),
+ multiRejectedDeferred: jQuery.Deferred().reject( "baz", "quux" ),
+ rejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ false ] ),
+ multiRejectedDeferredWith: jQuery.Deferred().rejectWith( sentinel, [ "baz", "quux" ] )
+ },
+ contexts = {
+ deferredWith: sentinel,
+ multiDeferredWith: sentinel,
+ rejectedDeferredWith: sentinel,
+ multiRejectedDeferredWith: sentinel
+ },
+ willSucceed = {
+ promise: [ true ],
+ deferred: [ true ],
+ eventuallyFulfilled: [ true ],
+ secondaryFulfilled: [ true ],
+ eventuallySecondaryFulfilled: [ true ],
+ multiDeferred: [ "foo", "bar" ],
+ deferredWith: [ true ],
+ multiDeferredWith: [ "foo", "bar" ]
+ },
+ willError = {
+ rejectedPromise: [ false ],
+ rejectedDeferred: [ false ],
+ eventuallyRejected: [ false ],
+ secondaryRejected: [ false ],
+ eventuallySecondaryRejected: [ false ],
+ multiRejectedDeferred: [ "baz", "quux" ],
+ rejectedDeferredWith: [ false ],
+ multiRejectedDeferredWith: [ "baz", "quux" ]
+ },
- var cache,
- context = {};
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ defaultContext = ( function getDefaultContext() { return this; } ).call(),
+
+ done = assert.async( CASES * 2 );
+
+ assert.expect( CASES * 4 );
+
+ jQuery.each( inputs, function( message, value ) {
+ var code = "jQuery.when( " + message + " )",
+ shouldResolve = willSucceed[ message ],
+ shouldError = willError[ message ],
+ context = contexts[ message ] || defaultContext,
+ onFulfilled = function( method ) {
+ var call = code + "." + method;
+ return function() {
+ if ( shouldResolve ) {
+ assert.deepEqual( slice.call( arguments ), shouldResolve,
+ call + " resolve" );
+ assert.strictEqual( this, context, call + " context" );
+ } else {
+ assert.ok( false, call + " resolve" );
+ }
+ done();
+ };
+ },
+ onRejected = function( method ) {
+ var call = code + "." + method;
+ return function() {
+ if ( shouldError ) {
+ assert.deepEqual( slice.call( arguments ), shouldError, call + " reject" );
+ assert.strictEqual( this, context, call + " context" );
+ } else {
+ assert.ok( false, call + " reject" );
+ }
+ done();
+ };
+ };
- jQuery.when( jQuery.Deferred().resolveWith( context ) ).done( function() {
- assert.strictEqual( this, context, "when( promise ) propagates context" );
+ jQuery.when( value )
+ .done( onFulfilled( "done" ) )
+ .fail( onRejected( "done" ) )
+ .then( onFulfilled( "then" ), onRejected( "then" ) );
} );
- jQuery.each( [ 1, 2, 3 ], function( k, i ) {
- jQuery.when( cache || jQuery.Deferred( function() {
- this.resolve( i );
- } )
- ).done( function( value ) {
- assert.strictEqual( value, 1, "Function executed" + ( i > 1 ? " only once" : "" ) );
- cache = value;
- } );
-
- } );
+ setTimeout( function() {
+ eventuallyFulfilled.resolve( true );
+ eventuallyRejected.reject( false );
+ inputs.eventuallySecondaryFulfilled.resolve( secondaryFulfilled );
+ inputs.eventuallySecondaryRejected.resolve( secondaryRejected );
+ }, 50 );
} );
-QUnit.test( "jQuery.when - joined", function( assert ) {
+QUnit.test( "jQuery.when(a, b) - like Promise.all", function( assert ) {
+ "use strict";
- assert.expect( 81 );
+ assert.expect( 196 );
- var deferreds = {
+ var slice = [].slice,
+ deferreds = {
rawValue: 1,
fulfilled: jQuery.Deferred().resolve( 1 ),
rejected: jQuery.Deferred().reject( 0 ),
@@ -791,44 +992,91 @@ QUnit.test( "jQuery.when - joined", function( assert ) {
eventuallyRejected: true,
rejectedStandardPromise: true
},
- counter = 49;
- QUnit.stop();
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ defaultContext = ( function getDefaultContext() { return this; } ).call(),
- function restart() {
- if ( !--counter ) {
- QUnit.start();
- }
- }
+ done = assert.async( 98 );
- jQuery.each( deferreds, function( id1, defer1 ) {
- jQuery.each( deferreds, function( id2, defer2 ) {
- var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
+ jQuery.each( deferreds, function( id1, v1 ) {
+ jQuery.each( deferreds, function( id2, v2 ) {
+ var code = "jQuery.when( " + id1 + ", " + id2 + " )",
+ shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
shouldError = willError[ id1 ] || willError[ id2 ],
- expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ],
- code = "jQuery.when( " + id1 + ", " + id2 + " )",
- context1 = defer1 && jQuery.isFunction( defer1.promise ) ? defer1.promise() : window,
- context2 = defer2 && jQuery.isFunction( defer2.promise ) ? defer2.promise() : window;
-
- jQuery.when( defer1, defer2 ).done( function( a, b ) {
- if ( shouldResolve ) {
- assert.deepEqual( [ a, b ], expected, code + " => resolve" );
- assert.strictEqual( this[ 0 ], context1, code + " => first context OK" );
- assert.strictEqual( this[ 1 ], context2, code + " => second context OK" );
- } else {
- assert.ok( false, code + " => resolve" );
- }
- } ).fail( function( a, b ) {
- if ( shouldError ) {
- assert.deepEqual( [ a, b ], expected, code + " => reject" );
- } else {
- assert.ok( false, code + " => reject" );
- }
- } ).always( restart );
+ expected = shouldResolve ? [ 1, 1 ] : [ 0 ],
+ context = shouldResolve ? [ defaultContext, defaultContext ] : defaultContext,
+ onFulfilled = function( method ) {
+ var call = code + "." + method;
+ return function() {
+ if ( shouldResolve ) {
+ assert.deepEqual( slice.call( arguments ), expected,
+ call + " resolve" );
+ assert.deepEqual( this, context, code + " context" );
+ } else {
+ assert.ok( false, call + " resolve" );
+ }
+ done();
+ };
+ },
+ onRejected = function( method ) {
+ var call = code + "." + method;
+ return function() {
+ if ( shouldError ) {
+ assert.deepEqual( slice.call( arguments ), expected, call + " reject" );
+ assert.deepEqual( this, context, code + " context" );
+ } else {
+ assert.ok( false, call + " reject" );
+ }
+ done();
+ };
+ };
+
+ jQuery.when( v1, v2 )
+ .done( onFulfilled( "done" ) )
+ .fail( onRejected( "done" ) )
+ .then( onFulfilled( "then" ), onRejected( "then" ) );
+ } );
+ } );
+
+ setTimeout( function() {
+ deferreds.eventuallyFulfilled.resolve( 1 );
+ deferreds.eventuallyRejected.reject( 0 );
+ }, 50 );
+} );
+
+QUnit.test( "jQuery.when - always returns a new promise", function( assert ) {
+
+ assert.expect( 42 );
+
+ jQuery.each( {
+ "no arguments": [],
+ "non-thenable": [ "foo" ],
+ "promise": [ Promise.resolve( "bar" ) ],
+ "rejected promise": [ Promise.reject( "bar" ) ],
+ "deferred": [ jQuery.Deferred().resolve( "baz" ) ],
+ "rejected deferred": [ jQuery.Deferred().reject( "baz" ) ],
+ "multi-resolved deferred": [ jQuery.Deferred().resolve( "qux", "quux" ) ],
+ "multiple non-thenables": [ "corge", "grault" ],
+ "multiple deferreds": [
+ jQuery.Deferred().resolve( "garply" ),
+ jQuery.Deferred().resolve( "waldo" )
+ ]
+ }, function( label, args ) {
+ var result = jQuery.when.apply( jQuery, args );
+
+ assert.ok( jQuery.isFunction( result.then ), "Thenable returned from " + label );
+ assert.strictEqual( result.resolve, undefined, "Non-deferred returned from " + label );
+ assert.strictEqual( result.promise(), result, "Promise returned from " + label );
+
+ jQuery.each( args, function( i, arg ) {
+ assert.notStrictEqual( result, arg, "Returns distinct from arg " + i + " of " + label );
+ if ( arg.promise ) {
+ assert.notStrictEqual( result, arg.promise(),
+ "Returns distinct from promise of arg " + i + " of " + label );
+ }
} );
} );
- deferreds.eventuallyFulfilled.resolve( 1 );
- deferreds.eventuallyRejected.reject( 0 );
} );
QUnit.test( "jQuery.when - notify does not affect resolved", function( assert ) {
@@ -848,106 +1096,27 @@ QUnit.test( "jQuery.when - notify does not affect resolved", function( assert )
} );
} );
-QUnit.test( "jQuery.when - filtering", function( assert ) {
-
- assert.expect( 2 );
-
- function increment( x ) {
- return x + 1;
- }
-
- QUnit.stop();
-
- jQuery.when(
- jQuery.Deferred().resolve( 3 ).then( increment ),
- jQuery.Deferred().reject( 5 ).then( null, increment )
- ).done( function( four, six ) {
- assert.strictEqual( four, 4, "resolved value incremented" );
- assert.strictEqual( six, 6, "rejected value incremented" );
- QUnit.start();
- } );
-} );
-
-QUnit.test( "jQuery.when - exceptions", function( assert ) {
-
- assert.expect( 2 );
-
- function woops() {
- throw "exception thrown";
- }
-
- QUnit.stop();
-
- jQuery.Deferred().resolve().then( woops ).fail( function( doneException ) {
- assert.strictEqual( doneException, "exception thrown", "throwing in done handler" );
- jQuery.Deferred().reject().then( null, woops ).fail( function( failException ) {
- assert.strictEqual( failException, "exception thrown", "throwing in fail handler" );
- QUnit.start();
- } );
- } );
-} );
-
-QUnit.test( "jQuery.when - chaining", function( assert ) {
-
- assert.expect( 4 );
-
- var defer = jQuery.Deferred();
-
- function chain() {
- return defer;
- }
-
- function chainStandard() {
- return Promise.resolve( "std deferred" );
- }
-
- QUnit.stop();
-
- jQuery.when(
- jQuery.Deferred().resolve( 3 ).then( chain ),
- jQuery.Deferred().reject( 5 ).then( null, chain ),
- jQuery.Deferred().resolve( 3 ).then( chainStandard ),
- jQuery.Deferred().reject( 5 ).then( null, chainStandard )
- ).done( function( v1, v2, s1, s2 ) {
- assert.strictEqual( v1, "other deferred", "chaining in done handler" );
- assert.strictEqual( v2, "other deferred", "chaining in fail handler" );
- assert.strictEqual( s1, "std deferred", "chaining thenable in done handler" );
- assert.strictEqual( s2, "std deferred", "chaining thenable in fail handler" );
- QUnit.start();
- } );
-
- defer.resolve( "other deferred" );
-} );
+QUnit.test( "jQuery.when(...) - opportunistically synchronous", function( assert ) {
-QUnit.test( "jQuery.when - solitary thenables", function( assert ) {
+ assert.expect( 5 );
- assert.expect( 1 );
-
- var done = assert.async(),
- rejected = new Promise( function( resolve, reject ) {
- setTimeout( function() {
- reject( "rejected" );
- }, 100 );
- } );
-
- jQuery.when( rejected ).then(
- function() {
- assert.ok( false, "Rejected, solitary, non-Deferred thenable should not resolve" );
- done();
+ var when = "before",
+ resolved = jQuery.Deferred().resolve( true ),
+ rejected = jQuery.Deferred().reject( false ),
+ validate = function( label ) {
+ return function() {
+ assert.equal( when, "before", label );
+ };
},
- function() {
- assert.ok( true, "Rejected, solitary, non-Deferred thenable rejected properly" );
- done();
- }
- );
-} );
-
-QUnit.test( "jQuery.when does not reuse a solitary jQuery Deferred (gh-2018)", function( assert ) {
+ done = assert.async( 5 );
- assert.expect( 2 );
- var defer = jQuery.Deferred().resolve(),
- promise = jQuery.when( defer );
+ jQuery.when().done( validate( "jQuery.when()" ) ).always( done );
+ jQuery.when( when ).done( validate( "jQuery.when(nonThenable)" ) ).always( done );
+ jQuery.when( resolved ).done( validate( "jQuery.when(alreadyFulfilled)" ) ).always( done );
+ jQuery.when( rejected ).fail( validate( "jQuery.when(alreadyRejected)" ) ).always( done );
+ jQuery.when( resolved, rejected )
+ .always( validate( "jQuery.when(alreadyFulfilled, alreadyRejected)" ) )
+ .always( done );
- assert.equal( promise.state(), "resolved", "Master Deferred is immediately resolved" );
- assert.notStrictEqual( defer.promise(), promise, "jQuery.when returns the master deferred's promise" );
+ when = "after";
} );
diff --git a/test/unit/deprecated.js b/test/unit/deprecated.js
index 797290f..27ba1cf 100644
--- a/test/unit/deprecated.js
+++ b/test/unit/deprecated.js
@@ -14,7 +14,7 @@ QUnit.test( "bind/unbind", function( assert ) {
assert.equal( e.type, "click", "correct event type" );
assert.equal( e.data.bindData, 19, "correct trigger data" );
assert.equal( trig, 42, "correct bind data" );
- assert.equal( e.target.nodeName.toLowerCase(), "b" , "correct element" );
+ assert.equal( e.target.nodeName.toLowerCase(), "b", "correct element" );
} )
.trigger( "click", [ 42 ] )
.unbind( "click" )
@@ -32,11 +32,81 @@ QUnit.test( "delegate/undelegate", function( assert ) {
markup
.delegate( "b", "click", function( e ) {
assert.equal( e.type, "click", "correct event type" );
- assert.equal( e.target.nodeName.toLowerCase(), "b" , "correct element" );
+ assert.equal( e.target.nodeName.toLowerCase(), "b", "correct element" );
} )
.find( "b" )
.trigger( "click" )
.end()
.undelegate( "b", "click" )
.remove();
-} );
\ No newline at end of file
+} );
+
+QUnit.test( "jQuery.parseJSON", function( assert ) {
+ assert.expect( 20 );
+
+ assert.strictEqual( jQuery.parseJSON( null ), null, "primitive null" );
+ assert.strictEqual( jQuery.parseJSON( "0.88" ), 0.88, "Number" );
+ assert.strictEqual(
+ jQuery.parseJSON( "\" \\\" \\\\ \\/ \\b \\f \\n \\r \\t \\u007E \\u263a \"" ),
+ " \" \\ / \b \f \n \r \t ~ \u263A ",
+ "String escapes"
+ );
+ assert.deepEqual( jQuery.parseJSON( "{}" ), {}, "Empty object" );
+ assert.deepEqual( jQuery.parseJSON( "{\"test\":1}" ), { "test": 1 }, "Plain object" );
+ assert.deepEqual( jQuery.parseJSON( "[0]" ), [ 0 ], "Simple array" );
+
+ assert.deepEqual(
+ jQuery.parseJSON( "[ \"string\", -4.2, 2.7180e0, 3.14E-1, {}, [], true, false, null ]" ),
+ [ "string", -4.2, 2.718, 0.314, {}, [], true, false, null ],
+ "Array of all data types"
+ );
+ assert.deepEqual(
+ jQuery.parseJSON( "{ \"string\": \"\", \"number\": 4.2e+1, \"object\": {}," +
+ "\"array\": [[]], \"boolean\": [ true, false ], \"null\": null }" ),
+ { string: "", number: 42, object: {}, array: [ [] ], "boolean": [ true, false ], "null": null },
+ "Dictionary of all data types"
+ );
+
+ assert.deepEqual( jQuery.parseJSON( "\n{\"test\":1}\t" ), { "test": 1 },
+ "Leading and trailing whitespace are ignored" );
+
+ assert.throws( function() {
+ jQuery.parseJSON();
+ }, null, "Undefined raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "" );
+ }, null, "Empty string raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "''" );
+ }, null, "Single-quoted string raises an error" );
+
+ assert.throws( function() {
+ var result = jQuery.parseJSON( "0101" );
+
+ // Support: IE <=9 only
+ // Ensure base-10 interpretation on browsers that erroneously accept leading-zero numbers
+ if ( result === 101 ) {
+ throw new Error( "close enough" );
+ }
+ }, null, "Leading-zero number raises an error or is parsed as decimal" );
+ assert.throws( function() {
+ jQuery.parseJSON( "{a:1}" );
+ }, null, "Unquoted property raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "{'a':1}" );
+ }, null, "Single-quoted property raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "[,]" );
+ }, null, "Array element elision raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "{},[]" );
+ }, null, "Comma expression raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "[]\n,{}" );
+ }, null, "Newline-containing comma expression raises an error" );
+ assert.throws( function() {
+ jQuery.parseJSON( "\"\"\n\"\"" );
+ }, null, "Automatic semicolon insertion raises an error" );
+
+ assert.strictEqual( jQuery.parseJSON( [ 0 ] ), 0, "Input cast to string" );
+} );
diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js
index c681478..5741b2a 100644
--- a/test/unit/dimensions.js
+++ b/test/unit/dimensions.js
@@ -295,7 +295,7 @@ QUnit.test( "child of a hidden elem (or unconnected node) has accurate inner/out
assert.equal( $divChild.outerWidth(), $divNormal.outerWidth(), "child of a hidden element outerWidth() is wrong see #9441" );
assert.equal( $divChild.outerWidth( true ), $divNormal.outerWidth( true ), "child of a hidden element outerWidth( true ) is wrong see #9300" );
- // Support: IE 10-11, Edge
+ // Support: IE 10 - 11, Edge 12 - 13+
// Child height is not always decimal
assert.equal( $divChild.height().toFixed( 3 ), $divNormal.height().toFixed( 3 ), "child of a hidden element height() is wrong see #9441" );
assert.equal( $divChild.innerHeight().toFixed( 3 ), $divNormal.innerHeight().toFixed( 3 ), "child of a hidden element innerHeight() is wrong see #9441" );
@@ -308,7 +308,7 @@ QUnit.test( "child of a hidden elem (or unconnected node) has accurate inner/out
assert.equal( $divUnconnected.outerWidth(), $divNormal.outerWidth(), "unconnected element outerWidth() is wrong see #9441" );
assert.equal( $divUnconnected.outerWidth( true ), $divNormal.outerWidth( true ), "unconnected element outerWidth( true ) is wrong see #9300" );
- // Support: IE 10-11, Edge
+ // Support: IE 10 - 11, Edge 12 - 13+
// Child height is not always decimal
assert.equal( $divUnconnected.height().toFixed( 3 ), $divNormal.height().toFixed( 3 ), "unconnected element height() is wrong see #9441" );
assert.equal( $divUnconnected.innerHeight().toFixed( 3 ), $divNormal.innerHeight().toFixed( 3 ), "unconnected element innerHeight() is wrong see #9441" );
@@ -372,7 +372,7 @@ QUnit.test( "box-sizing:border-box child of a hidden elem (or unconnected node)
assert.equal( $divChild.outerWidth(), $divNormal.outerWidth(), "child of a hidden element outerWidth() is wrong see #10413" );
assert.equal( $divChild.outerWidth( true ), $divNormal.outerWidth( true ), "child of a hidden element outerWidth( true ) is wrong see #10413" );
- // Support: IE 10-11, Edge
+ // Support: IE 10 - 11, Edge 12 - 13+
// Child height is not always decimal
assert.equal( $divChild.height().toFixed( 3 ), $divNormal.height().toFixed( 3 ), "child of a hidden element height() is wrong see #10413" );
assert.equal( $divChild.innerHeight().toFixed( 3 ), $divNormal.innerHeight().toFixed( 3 ), "child of a hidden element innerHeight() is wrong see #10413" );
@@ -385,7 +385,7 @@ QUnit.test( "box-sizing:border-box child of a hidden elem (or unconnected node)
assert.equal( $divUnconnected.outerWidth(), $divNormal.outerWidth(), "unconnected element outerWidth() is wrong see #10413" );
assert.equal( $divUnconnected.outerWidth( true ), $divNormal.outerWidth( true ), "unconnected element outerWidth( true ) is wrong see #10413" );
- // Support: IE 10-11, Edge
+ // Support: IE 10 - 11, Edge 12 - 13+
// Child height is not always decimal
assert.equal( $divUnconnected.height().toFixed( 3 ), $divNormal.height().toFixed( 3 ), "unconnected element height() is wrong see #10413" );
assert.equal( $divUnconnected.innerHeight().toFixed( 3 ), $divNormal.innerHeight().toFixed( 3 ), "unconnected element innerHeight() is wrong see #10413" );
@@ -406,11 +406,13 @@ QUnit.test( "passing undefined is a setter #5571", function( assert ) {
} );
QUnit.test( "setters with and without box-sizing:border-box", function( assert ) {
- assert.expect( 60 );
+ assert.expect( 120 );
- var parent = jQuery( "#foo" ).css({ width: "200px", height: "200px", "font-size": "16px" }),
+ var parent = jQuery( "#foo" ).css( { width: "200px", height: "200px", "font-size": "16px" } ),
el_bb = jQuery( "<div style='margin:5px;padding:1px;border:2px solid black;box-sizing:border-box;'></div>" ).appendTo( parent ),
- el = jQuery( "<div style='margin:5px;padding:1px;border:2px solid black;'></div>" ).appendTo( parent );
+ el = jQuery( "<div style='margin:5px;padding:1px;border:2px solid black;'></div>" ).appendTo( parent ),
+ el_bb_np = jQuery( "<div style='margin:5px; padding:0px; border:0px solid green;box-sizing:border-box;'></div>" ).appendTo( parent ),
+ el_np = jQuery( "<div style='margin:5px; padding:0px; border:0px solid green;'></div>" ).appendTo( parent );
jQuery.each( {
"number": { set: 100, expected: 100 },
@@ -421,32 +423,56 @@ QUnit.test( "setters with and without box-sizing:border-box", function( assert )
assert.equal( el_bb.innerWidth( values.set ).width(), values.expected - 2, "test border-box innerWidth(" + units + ") by roundtripping" );
assert.equal( el_bb.outerWidth( values.set ).width(), values.expected - 6, "test border-box outerWidth(" + units + ") by roundtripping" );
assert.equal( el_bb.outerWidth( values.set, false ).width(), values.expected - 6, "test border-box outerWidth(" + units + ", false) by roundtripping" );
- assert.equal( el_bb.outerWidth( values.set, true ).width(), values.expected - 16, "test border-box innerWidth(" + units + ", true) by roundtripping" );
+ assert.equal( el_bb.outerWidth( values.set, true ).width(), values.expected - 16, "test border-box outerWidth(" + units + ", true) by roundtripping" );
assert.equal( el_bb.height( values.set ).height(), values.expected, "test border-box height(" + units + ") by roundtripping" );
assert.equal( el_bb.innerHeight( values.set ).height(), values.expected - 2, "test border-box innerHeight(" + units + ") by roundtripping" );
assert.equal( el_bb.outerHeight( values.set ).height(), values.expected - 6, "test border-box outerHeight(" + units + ") by roundtripping" );
assert.equal( el_bb.outerHeight( values.set, false ).height(), values.expected - 6, "test border-box outerHeight(" + units + ", false) by roundtripping" );
- assert.equal( el_bb.outerHeight( values.set, true ).height(), values.expected - 16, "test border-box innerHeight(" + units + ", true) by roundtripping" );
+ assert.equal( el_bb.outerHeight( values.set, true ).height(), values.expected - 16, "test border-box outerHeight(" + units + ", true) by roundtripping" );
assert.equal( el.width( values.set ).width(), values.expected, "test non-border-box width(" + units + ") by roundtripping" );
assert.equal( el.innerWidth( values.set ).width(), values.expected - 2, "test non-border-box innerWidth(" + units + ") by roundtripping" );
assert.equal( el.outerWidth( values.set ).width(), values.expected - 6, "test non-border-box outerWidth(" + units + ") by roundtripping" );
assert.equal( el.outerWidth( values.set, false ).width(), values.expected - 6, "test non-border-box outerWidth(" + units + ", false) by roundtripping" );
- assert.equal( el.outerWidth( values.set, true ).width(), values.expected - 16, "test non-border-box innerWidth(" + units + ", true) by roundtripping" );
+ assert.equal( el.outerWidth( values.set, true ).width(), values.expected - 16, "test non-border-box outerWidth(" + units + ", true) by roundtripping" );
assert.equal( el.height( values.set ).height(), values.expected, "test non-border-box height(" + units + ") by roundtripping" );
assert.equal( el.innerHeight( values.set ).height(), values.expected - 2, "test non-border-box innerHeight(" + units + ") by roundtripping" );
assert.equal( el.outerHeight( values.set ).height(), values.expected - 6, "test non-border-box outerHeight(" + units + ") by roundtripping" );
assert.equal( el.outerHeight( values.set, false ).height(), values.expected - 6, "test non-border-box outerHeight(" + units + ", false) by roundtripping" );
- assert.equal( el.outerHeight( values.set, true ).height(), values.expected - 16, "test non-border-box innerHeight(" + units + ", true) by roundtripping" );
+ assert.equal( el.outerHeight( values.set, true ).height(), values.expected - 16, "test non-border-box outerHeight(" + units + ", true) by roundtripping" );
+
+ assert.equal( el_bb_np.width( values.set ).width(), values.expected, "test border-box width and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.innerWidth( values.set ).width(), values.expected, "test border-box innerWidth and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.outerWidth( values.set ).width(), values.expected, "test border-box outerWidth and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.outerWidth( values.set, false ).width(), values.expected, "test border-box outerWidth and negative padding(" + units + ", false) by roundtripping" );
+ assert.equal( el_bb_np.outerWidth( values.set, true ).width(), values.expected - 10, "test border-box outerWidth and negative padding(" + units + ", true) by roundtripping" );
+
+ assert.equal( el_bb_np.height( values.set ).height(), values.expected, "test border-box height and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.innerHeight( values.set ).height(), values.expected, "test border-box innerHeight and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.outerHeight( values.set ).height(), values.expected, "test border-box outerHeight and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_bb_np.outerHeight( values.set, false ).height(), values.expected, "test border-box outerHeight and negative padding(" + units + ", false) by roundtripping" );
+ assert.equal( el_bb_np.outerHeight( values.set, true ).height(), values.expected - 10, "test border-box outerHeight and negative padding(" + units + ", true) by roundtripping" );
+
+ assert.equal( el_np.width( values.set ).width(), values.expected, "test non-border-box width and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.innerWidth( values.set ).width(), values.expected, "test non-border-box innerWidth and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.outerWidth( values.set ).width(), values.expected, "test non-border-box outerWidth and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.outerWidth( values.set, false ).width(), values.expected, "test non-border-box outerWidth and negative padding(" + units + ", false) by roundtripping" );
+ assert.equal( el_np.outerWidth( values.set, true ).width(), values.expected - 10, "test non-border-box outerWidth and negative padding(" + units + ", true) by roundtripping" );
+
+ assert.equal( el_np.height( values.set ).height(), values.expected, "test non-border-box height and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.innerHeight( values.set ).height(), values.expected, "test non-border-box innerHeight and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.outerHeight( values.set ).height(), values.expected, "test non-border-box outerHeight and negative padding(" + units + ") by roundtripping" );
+ assert.equal( el_np.outerHeight( values.set, false ).height(), values.expected, "test non-border-box outerHeight and negative padding(" + units + ", false) by roundtripping" );
+ assert.equal( el_np.outerHeight( values.set, true ).height(), values.expected - 10, "test non-border-box outerHeight and negative padding(" + units + ", true) by roundtripping" );
} );
} );
testIframe(
- "dimensions/documentLarge",
"window vs. large document",
- function( jQuery, window, document, assert ) {
+ "dimensions/documentLarge.html",
+ function( assert, jQuery, window, document ) {
assert.expect( 2 );
assert.ok( jQuery( document ).height() > jQuery( window ).height(), "document height is larger than window height" );
@@ -471,4 +497,34 @@ QUnit.test( "allow modification of coordinates argument (gh-1848)", function( as
"coordinates are modified (got offset.top: " + offsetTop + ")" );
} );
+QUnit.test( "outside view position (gh-2836)", function( assert ) {
+
+ // This test ported from gh-2836 example
+ assert.expect( 1 );
+
+ var parent,
+ html = [
+ "<div id=div-gh-2836>",
+ "<div></div>",
+ "<div></div>",
+ "<div></div>",
+ "<div></div>",
+ "<div></div>",
+ "</div>"
+ ].join( "" ),
+ stop = assert.async();
+
+ parent = jQuery( html );
+ parent.appendTo( "#qunit-fixture" );
+
+ parent.one( "scroll", function() {
+ var pos = parent.find( "div" ).eq( 3 ).position();
+
+ assert.strictEqual( pos.top, -100 );
+ stop();
+ } );
+
+ parent.scrollTop( 400 );
+} );
+
} )();
diff --git a/test/unit/effects.js b/test/unit/effects.js
index ae43674..eafe4b1 100644
--- a/test/unit/effects.js
+++ b/test/unit/effects.js
@@ -50,7 +50,7 @@ QUnit.test( "show() basic", function( assert ) {
QUnit.test( "show()", function( assert ) {
assert.expect( 27 );
- var div, speeds, old, test,
+ var div, speeds, test,
hiddendiv = jQuery( "div.hidden" );
assert.equal( jQuery.css( hiddendiv[ 0 ], "display" ), "none", "hiddendiv is display: none" );
@@ -99,13 +99,9 @@ QUnit.test( "show()", function( assert ) {
"<div id='show-tests'>" +
"<div><p><a href='#'></a></p><code></code><pre></pre><span></span></div>" +
"<table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody></table>" +
- "<ul><li></li></ul></div>" +
- "<table id='test-table'></table>"
+ "<ul><li></li></ul></div>"
).appendTo( "#qunit-fixture" ).find( "*" ).css( "display", "none" );
- old = jQuery( "#test-table" ).show().css( "display" ) !== "table";
- jQuery( "#test-table" ).remove();
-
test = {
"div": "block",
"p": "block",
@@ -113,14 +109,14 @@ QUnit.test( "show()", function( assert ) {
"code": "inline",
"pre": "block",
"span": "inline",
- "table": old ? "block" : "table",
- "thead": old ? "block" : "table-header-group",
- "tbody": old ? "block" : "table-row-group",
- "tr": old ? "block" : "table-row",
- "th": old ? "block" : "table-cell",
- "td": old ? "block" : "table-cell",
+ "table": "table",
+ "thead": "table-header-group",
+ "tbody": "table-row-group",
+ "tr": "table-row",
+ "th": "table-cell",
+ "td": "table-cell",
"ul": "block",
- "li": old ? "block" : "list-item"
+ "li": "list-item"
};
jQuery.each( test, function( selector, expected ) {
@@ -144,34 +140,28 @@ supportjQuery.each( hideOptions, function( type, setup ) {
"<div><p><a href='#'></a></p><code></code><pre></pre><span></span></div>" +
"<table><thead><tr><th></th></tr></thead><tbody><tr><td></td></tr></tbody>" +
"</table>" +
- "<ul><li></li></ul></div>" +
- "<table id='test-table'></table>"
+ "<ul><li></li></ul></div>"
).appendTo( "#qunit-fixture" ).find( "*" ).each( setup );
- var test,
- old = jQuery( "#test-table" ).show().css( "display" ) !== "table";
-
- jQuery( "#test-table" ).remove();
-
// Note: inline elements are expected to be inline-block
// because we're showing width/height
// Can't animate width/height inline
// See #14344
- test = {
+ var test = {
"div": "block",
"p": "block",
"a": "inline",
"code": "inline",
"pre": "block",
"span": "inline",
- "table": old ? "block" : "table",
- "thead": old ? "block" : "table-header-group",
- "tbody": old ? "block" : "table-row-group",
- "tr": old ? "block" : "table-row",
- "th": old ? "block" : "table-cell",
- "td": old ? "block" : "table-cell",
+ "table": "table",
+ "thead": "table-header-group",
+ "tbody": "table-row-group",
+ "tr": "table-row",
+ "th": "table-cell",
+ "td": "table-cell",
"ul": "block",
- "li": old ? "block" : "list-item"
+ "li": "list-item"
};
jQuery.each( test, function( selector ) {
@@ -369,10 +359,8 @@ QUnit.test( "animate block width/height", function( assert ) {
QUnit.test( "animate table width/height", function( assert ) {
assert.expect( 1 );
- var displayMode = jQuery( "#table" ).css( "display" ) !== "table" ? "block" : "table";
-
jQuery( "#table" ).animate( { width: 42, height: 42 }, 100, function() {
- assert.equal( jQuery( this ).css( "display" ), displayMode, "display mode is correct" );
+ assert.equal( jQuery( this ).css( "display" ), "table", "display mode is correct" );
} );
this.clock.tick( 100 );
} );
@@ -550,7 +538,7 @@ QUnit.test( "animate duration 0", function( assert ) {
assert.expect( 11 );
var $elem,
- $elems = jQuery( [ { a:0 },{ a:0 } ] ),
+ $elems = jQuery( [ { a:0 }, { a:0 } ] ),
counter = 0;
assert.equal( jQuery.timers.length, 0, "Make sure no animation was running from another test" );
@@ -661,35 +649,44 @@ QUnit.test( "stop()", function( assert ) {
this.clock.tick( 100 );
} );
-QUnit.test( "stop() - several in queue", function( assert ) {
- assert.expect( 5 );
+// In IE9 inside testswarm this test doesn't work properly
+( function() {
+ var type = "test";
- var nw, $foo = jQuery( "#foo" );
+ if ( QUnit.isSwarm && /msie 9\.0/i.test( window.navigator.userAgent ) ) {
+ type = "skip";
+ }
- // default duration is 400ms, so 800px ensures we aren't 0 or 1 after 1ms
- $foo.hide().css( "width", 800 );
+ QUnit[ type ]( "stop() - several in queue", function( assert ) {
+ assert.expect( 5 );
- $foo.animate( { "width": "show" }, 400, "linear" );
- $foo.animate( { "width": "hide" } );
- $foo.animate( { "width": "show" } );
+ var nw, $foo = jQuery( "#foo" );
- this.clock.tick( 1 );
+ // default duration is 400ms, so 800px ensures we aren't 0 or 1 after 1ms
+ $foo.hide().css( "width", 800 );
- jQuery.fx.tick();
- assert.equal( $foo.queue().length, 3, "3 in the queue" );
+ $foo.animate( { "width": "show" }, 400, "linear" );
+ $foo.animate( { "width": "hide" } );
+ $foo.animate( { "width": "show" } );
- nw = $foo.css( "width" );
- assert.notEqual( parseFloat( nw ), 1, "An animation occurred " + nw );
- $foo.stop();
+ this.clock.tick( 1 );
- assert.equal( $foo.queue().length, 2, "2 in the queue" );
- nw = $foo.css( "width" );
- assert.notEqual( parseFloat( nw ), 1, "Stop didn't reset the animation " + nw );
+ jQuery.fx.tick();
+ assert.equal( $foo.queue().length, 3, "3 in the queue" );
- $foo.stop( true );
+ nw = $foo.css( "width" );
+ assert.notEqual( parseFloat( nw ), 1, "An animation occurred " + nw );
+ $foo.stop();
- assert.equal( $foo.queue().length, 0, "0 in the queue" );
-} );
+ assert.equal( $foo.queue().length, 2, "2 in the queue" );
+ nw = $foo.css( "width" );
+ assert.notEqual( parseFloat( nw ), 1, "Stop didn't reset the animation " + nw );
+
+ $foo.stop( true );
+
+ assert.equal( $foo.queue().length, 0, "0 in the queue" );
+ } );
+} )();
QUnit.test( "stop(clearQueue)", function( assert ) {
assert.expect( 4 );
@@ -1031,7 +1028,7 @@ jQuery.each( {
jQuery( elem ).remove();
} );
- this.clock.tick( 50 );
+ this.clock.tick( 100 );
} );
} );
} );
@@ -1389,13 +1386,7 @@ QUnit.test( "Do not append px to 'fill-opacity' #9548", function( assert ) {
var $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" );
$div.css( "fill-opacity", 0 ).animate( { "fill-opacity": 1.0 }, 0, function() {
-
- // Support: Android 2.3 (no support for fill-opacity)
- if ( jQuery( this ).css( "fill-opacity" ) ) {
- assert.equal( jQuery( this ).css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" );
- } else {
- assert.ok( true, "No support for fill-opacity CSS property" );
- }
+ assert.equal( jQuery( this ).css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" );
$div.remove();
} );
} );
@@ -1556,15 +1547,17 @@ QUnit.test( "animate should set display for disconnected nodes", function( asser
assert.expect( 20 );
var env = this,
- methods = {
- toggle: [ 1 ],
- slideToggle: [],
+ showMethods = {
fadeIn: [],
fadeTo: [ "fast", 0.5 ],
slideDown: [ "fast" ],
show: [ 1 ],
animate: [ { width: "show" } ]
},
+ toggleMethods = {
+ toggle: [ 1 ],
+ slideToggle: []
+ },
$divEmpty = jQuery( "<div/>" ),
$divTest = jQuery( "<div>test</div>" ),
$divNone = jQuery( "<div style='display: none;'/>" ),
@@ -1587,7 +1580,7 @@ QUnit.test( "animate should set display for disconnected nodes", function( asser
assert.expectJqData( env, $divNone[ 0 ], "olddisplay" );
- jQuery.each( methods, function( name, opt ) {
+ jQuery.each( showMethods, function( name, opt ) {
jQuery.fn[ name ].apply( jQuery( "<div/>" ), opt.concat( [ function() {
assert.strictEqual( jQuery( this ).css( "display" ), nullParentDisplay,
"." + name + " block with null parentNode" );
@@ -1598,6 +1591,17 @@ QUnit.test( "animate should set display for disconnected nodes", function( asser
"." + name + " block under fragment" );
} ] ) );
} );
+ jQuery.each( toggleMethods, function( name, opt ) {
+ jQuery.fn[ name ].apply( jQuery( "<div/>" ), opt.concat( [ function() {
+ assert.strictEqual( jQuery( this ).css( "display" ), "none",
+ "." + name + " block with null parentNode" );
+ } ] ) );
+
+ jQuery.fn[ name ].apply( jQuery( "<div>test</div>" ), opt.concat( [ function() {
+ assert.strictEqual( jQuery( this ).css( "display" ), "none",
+ "." + name + " block under fragment" );
+ } ] ) );
+ } );
clock.tick( 400 );
} );
@@ -1841,7 +1845,7 @@ QUnit.test( "non-px animation handles non-numeric start (#11971)", function( ass
this.clock.tick( 10 );
} );
-QUnit.test("Animation callbacks (#11797)", function( assert ) {
+QUnit.test( "Animation callbacks (#11797)", function( assert ) {
assert.expect( 16 );
var prog = 0,
@@ -1962,7 +1966,7 @@ QUnit.test( "Animation callbacks in order (#2292)", function( assert ) {
always: function() {
assert.step( 5 );
}
- }).finish();
+ } ).finish();
this.clock.tick( dur + 10 );
} );
diff --git a/test/unit/event.js b/test/unit/event.js
index 4a5611b..02aad5e 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -5,6 +5,28 @@ QUnit.module( "event", {
teardown: moduleTeardown
} );
+QUnit.test( "null or undefined handler", function( assert ) {
+ assert.expect( 4 );
+
+ // Supports Fixes bug #7229
+ try {
+ jQuery( "#firstp" ).on( "click", null );
+ assert.ok( true, "Passing a null handler will not throw an exception" );
+ } catch ( e ) {}
+
+ try {
+ jQuery( "#firstp" ).on( "click", undefined );
+ assert.ok( true, "Passing an undefined handler will not throw an exception" );
+ } catch ( e ) {}
+
+ var expectedElem = jQuery( "#firstp" );
+ var actualElem = expectedElem.on( "click", null );
+ assert.equal( actualElem, expectedElem, "Passing a null handler should return the original element" );
+
+ actualElem = expectedElem.on( "click", undefined );
+ assert.equal( actualElem, expectedElem, "Passing a null handler should return the original element" );
+} );
+
QUnit.test( "on() with non-null,defined data", function( assert ) {
assert.expect( 2 );
@@ -56,7 +78,7 @@ QUnit.test( "on(), with data", function( assert ) {
handler = function( event ) {
assert.ok( event.data, "on() with data, check passed data exists" );
- assert.equal( event.data[ "foo" ], "bar", "on() with data, Check value of passed data" );
+ assert.equal( event.data.foo, "bar", "on() with data, Check value of passed data" );
};
jQuery( "#firstp" ).on( "click", { "foo": "bar" }, handler ).trigger( "click" ).off( "click", handler );
@@ -73,7 +95,7 @@ QUnit.test( "click(), with data", function( assert ) {
assert.expect( 3 );
var handler = function( event ) {
assert.ok( event.data, "on() with data, check passed data exists" );
- assert.equal( event.data[ "foo" ], "bar", "on() with data, Check value of passed data" );
+ assert.equal( event.data.foo, "bar", "on() with data, Check value of passed data" );
};
jQuery( "#firstp" ).on( "click", { "foo": "bar" }, handler ).trigger( "click" ).off( "click", handler );
@@ -177,7 +199,7 @@ QUnit.test( "on(), namespace with special add", function( assert ) {
assert.ok( true, "Test event fired." );
} );
- jQuery.event.special[ "test" ] = {
+ jQuery.event.special.test = {
_default: function( e, data ) {
assert.equal( e.type, "test", "Make sure we're dealing with a test event." );
assert.ok( data, "And that trigger data was passed." );
@@ -229,7 +251,7 @@ QUnit.test( "on(), namespace with special add", function( assert ) {
// Should trigger 2
div.appendTo( "#qunit-fixture" ).remove();
- delete jQuery.event.special[ "test" ];
+ delete jQuery.event.special.test;
} );
QUnit.test( "on(), no data", function( assert ) {
@@ -409,20 +431,13 @@ QUnit.test( "on bubbling, isDefaultPrevented, stopImmediatePropagation", functio
$anchor2.off( "click" );
$main.off( "click", "**" );
- // Android 2.3 doesn't support stopImmediatePropagation; jQuery fallbacks to stopPropagation
- // in such a case.
- // Support: Android 2.3
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- assert.ok( true, "Android 2.3, skipping native stopImmediatePropagation check" );
- } else {
- $anchor2.on( "click", function( e ) {
- e.stopImmediatePropagation();
- assert.ok( true, "anchor was clicked and prop stopped" );
- } );
- $anchor2[ 0 ].addEventListener( "click", neverCallMe, false );
- fakeClick( $anchor2 );
- $anchor2[ 0 ].removeEventListener( "click", neverCallMe );
- }
+ $anchor2.on( "click", function( e ) {
+ e.stopImmediatePropagation();
+ assert.ok( true, "anchor was clicked and prop stopped" );
+ } );
+ $anchor2[ 0 ].addEventListener( "click", neverCallMe, false );
+ fakeClick( $anchor2 );
+ $anchor2[ 0 ].removeEventListener( "click", neverCallMe );
} );
QUnit.test( "on(), iframes", function( assert ) {
@@ -711,8 +726,8 @@ QUnit.test( "on()/trigger()/off() on plain object", function( assert ) {
events = jQuery._data( obj, "events" );
assert.ok( events, "Object has events bound." );
assert.equal( obj[ "events" ], undefined, "Events object on plain objects is not events" );
- assert.equal( obj[ "test" ], undefined, "Make sure that test event is not on the plain object." );
- assert.equal( obj[ "handle" ], undefined, "Make sure that the event handler is not on the plain object." );
+ assert.equal( obj.test, undefined, "Make sure that test event is not on the plain object." );
+ assert.equal( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
// Should trigger 1
jQuery( obj ).trigger( "test" );
@@ -1177,7 +1192,7 @@ QUnit.test( "trigger(eventObject, [data], [fn])", function( assert ) {
//$child.on("foo", error );
event = new jQuery.Event( "foo" );
- $child.trigger( event, [ 1,2,3 ] ).off();
+ $child.trigger( event, [ 1, 2, 3 ] ).off();
assert.equal( event.result, "result", "Check event.result attribute" );
// Will error if it bubbles
@@ -1274,6 +1289,21 @@ QUnit.test( "Delegated events in SVG (#10791; #13180)", function( assert ) {
jQuery( "#qunit-fixture" ).off( "click" );
} );
+QUnit.test( "Delegated events with malformed selectors (gh-3071)", function( assert ) {
+ assert.expect( 3 );
+
+ assert.throws( function() {
+ jQuery( "#foo" ).on( "click", ":not", function() {} );
+ }, "malformed selector throws on attach" );
+
+ assert.throws( function() {
+ jQuery( "#foo" ).on( "click", "nonexistent:not", function() {} );
+ }, "short-circuitable malformed selector throws on attach" );
+
+ jQuery( "#foo > :first-child" ).click();
+ assert.ok( true, "malformed selector does not throw on event" );
+} );
+
QUnit.test( "Delegated events in forms (#10844; #11145; #8165; #11382, #11764)", function( assert ) {
assert.expect( 5 );
@@ -1367,29 +1397,26 @@ QUnit.test( "Submit event can be stopped (#11049)", function( assert ) {
form.remove();
} );
-// Test beforeunload event only if it supported.
-// Support: iOS 7+, Android<4.0
-// iOS & old Android have the window.onbeforeunload field but don't support the beforeunload
+// Support: iOS 7 - 9
+// iOS has the window.onbeforeunload field but doesn't support the beforeunload
// handler making it impossible to feature-detect the support.
-if ( window.onbeforeunload === null &&
- !/(ipad|iphone|ipod|android 2\.3)/i.test( navigator.userAgent ) ) {
- QUnit.test( "on(beforeunload)", 1, function( assert ) {
- var iframe = jQuery( jQuery.parseHTML( "<iframe src='data/event/onbeforeunload.html'><iframe>" ) );
- var done = assert.async();
+QUnit[ /(ipad|iphone|ipod)/i.test( navigator.userAgent ) ? "skip" : "test" ](
+ "on(beforeunload)", 1, function( assert ) {
+ var iframe = jQuery( jQuery.parseHTML( "<iframe src='data/event/onbeforeunload.html'><iframe>" ) );
+ var done = assert.async();
- window.onmessage = function( event ) {
- var payload = JSON.parse( event.data );
+ window.onmessage = function( event ) {
+ var payload = JSON.parse( event.data );
- assert.ok( payload.event, "beforeunload", "beforeunload event" );
+ assert.ok( payload.event, "beforeunload", "beforeunload event" );
- iframe.remove();
- window.onmessage = null;
- done();
- };
+ iframe.remove();
+ window.onmessage = null;
+ done();
+ };
- iframe.appendTo( "#qunit-fixture" );
- } );
-}
+ iframe.appendTo( "#qunit-fixture" );
+} );
QUnit.test( "jQuery.Event( type, props )", function( assert ) {
@@ -1574,7 +1601,7 @@ QUnit.test( ".on()/.off()", function( assert ) {
// Test binding with different this object
jQuery( "#body" ).on( "click", "#foo", jQuery.proxy( function() {
- assert.equal( this[ "foo" ], "bar", "on with event scope" ); }, { "foo": "bar" }
+ assert.equal( this.foo, "bar", "on with event scope" ); }, { "foo": "bar" }
) );
jQuery( "#foo" ).trigger( "click" );
jQuery( "#body" ).off( "click", "#foo" );
@@ -1833,7 +1860,7 @@ QUnit.test( "ignore comment nodes in event delegation (gh-2055)", function( asse
.appendTo( $foo.find( "#sap" ) );
if ( !test() ) {
- fireNative( $comment[0], "DOMNodeInserted" );
+ fireNative( $comment[ 0 ], "DOMNodeInserted" );
}
} );
@@ -2207,7 +2234,7 @@ QUnit.test( ".on and .off", function( assert ) {
QUnit.test( "special on name mapping", function( assert ) {
assert.expect( 7 );
- jQuery.event.special[ "slap" ] = {
+ jQuery.event.special.slap = {
bindType: "click",
delegateType: "swing",
handle: function( event ) {
@@ -2238,9 +2265,9 @@ QUnit.test( "special on name mapping", function( assert ) {
.trigger( "swing" )
.end()
.remove();
- delete jQuery.event.special[ "slap" ];
+ delete jQuery.event.special.slap;
- jQuery.event.special[ "gutfeeling" ] = {
+ jQuery.event.special.gutfeeling = {
bindType: "click",
delegateType: "click",
handle: function( event ) {
@@ -2329,9 +2356,9 @@ QUnit.test( "clone() delegated events (#11076)", function( assert ) {
clone = table.clone( true );
clone.find( "td" ).trigger( "click" );
- assert.equal( counter[ "center" ], 1, "first child" );
- assert.equal( counter[ "fold" ], 1, "last child" );
- assert.equal( counter[ "centerfold" ], 2, "all children" );
+ assert.equal( counter.center, 1, "first child" );
+ assert.equal( counter.fold, 1, "last child" );
+ assert.equal( counter.centerfold, 2, "all children" );
table.remove();
clone.remove();
@@ -2384,7 +2411,8 @@ QUnit.test( "event object properties on natively-triggered event", function( ass
$link = jQuery( link ),
evt = document.createEvent( "MouseEvents" );
- // IE9+ requires element to be in the body before it will dispatch
+ // Support: IE <=9 - 11 only
+ // IE requires element to be in the body before it will dispatch
$link.appendTo( "body" ).on( "click", function( e ) {
// Not trying to assert specific values here, just ensure the property exists
@@ -2397,36 +2425,28 @@ QUnit.test( "event object properties on natively-triggered event", function( ass
$link.off( "click" ).remove();
} );
-QUnit.test( "fixHooks extensions", function( assert ) {
+QUnit.test( "addProp extensions", function( assert ) {
assert.expect( 2 );
- // IE requires focusable elements to be visible, so append to body
- var $fixture = jQuery( "<input type='text' id='hook-fixture' />" ).appendTo( "body" ),
- saved = jQuery.event.fixHooks.click;
+ var $fixture = jQuery( "<div>" ).appendTo( "#qunit-fixture" );
// Ensure the property doesn't exist
$fixture.on( "click", function( event ) {
- assert.ok( !( "blurrinessLevel" in event ), "event.blurrinessLevel does not exist" );
+ assert.ok( !( "testProperty" in event ), "event.testProperty does not exist" );
} );
fireNative( $fixture[ 0 ], "click" );
$fixture.off( "click" );
- jQuery.event.fixHooks.click = {
- filter: function( event ) {
- event.blurrinessLevel = 42;
- return event;
- }
- };
+ jQuery.event.addProp( "testProperty", function() { return 42; } );
// Trigger a native click and ensure the property is set
$fixture.on( "click", function( event ) {
- assert.equal( event.blurrinessLevel, 42, "event.blurrinessLevel was set" );
+ assert.equal( event.testProperty, 42, "event.testProperty getter was invoked" );
} );
fireNative( $fixture[ 0 ], "click" );
+ $fixture.off( "click" );
- delete jQuery.event.fixHooks.click;
- $fixture.off( "click" ).remove();
- jQuery.event.fixHooks.click = saved;
+ $fixture.remove();
} );
QUnit.test( "drag/drop events copy mouse-related event properties (gh-1925, gh-2009)", function( assert ) {
@@ -2463,10 +2483,10 @@ QUnit.test( "focusin using non-element targets", function( assert ) {
} );
-testIframeWithCallback(
+testIframe(
"focusin from an iframe",
"event/focusinCrossFrame.html",
- function( frameDoc, assert ) {
+ function( assert, framejQuery, frameWin, frameDoc ) {
assert.expect( 1 );
var input = jQuery( frameDoc ).find( "#frame-input" );
@@ -2494,10 +2514,10 @@ testIframeWithCallback(
}
);
-testIframeWithCallback(
+testIframe(
"jQuery.ready promise",
"event/promiseReady.html",
- function( isOk, assert ) {
+ function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "$.when( $.ready ) works" );
}
@@ -2505,29 +2525,29 @@ testIframeWithCallback(
// need PHP here to make the incepted IFRAME hang
if ( hasPHP ) {
- testIframeWithCallback(
+ testIframe(
"jQuery.ready uses interactive",
"event/interactiveReady.html",
- function( isOk, assert ) {
+ function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "jQuery fires ready when the DOM can truly be interacted with" );
}
);
}
-testIframeWithCallback(
+testIframe(
"Focusing iframe element",
"event/focusElem.html",
- function( isOk, assert ) {
+ function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "Focused an element in an iframe" );
}
);
-testIframeWithCallback(
+testIframe(
"triggerHandler(onbeforeunload)",
"event/triggerunload.html",
- function( isOk, assert ) {
+ function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "Triggered onbeforeunload without an error" );
}
@@ -2535,10 +2555,10 @@ testIframeWithCallback(
// need PHP here to make the incepted IFRAME hang
if ( hasPHP ) {
- testIframeWithCallback(
+ testIframe(
"jQuery.ready synchronous load with long loading subresources",
"event/syncReady.html",
- function( isOk, assert ) {
+ function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "jQuery loaded synchronously fires ready when the DOM can truly be interacted with" );
}
@@ -2556,7 +2576,7 @@ QUnit.test( "change handler should be detached from element", function( assert )
originRemoveEvent( elem, type, handle );
};
- jQuery.removeEvent = wrapperRemoveEvent ;
+ jQuery.removeEvent = wrapperRemoveEvent;
$fixture.on( "change", function() {} );
$fixture.off( "change" );
@@ -2716,6 +2736,15 @@ QUnit.test( ".off() removes the expando when there's no more data", function( as
}
} );
+QUnit.test( "jQuery.Event( src ) does not require a target property", function( assert ) {
+ assert.expect( 2 );
+
+ var event = jQuery.Event( { type: "offtarget" } );
+
+ assert.equal( event.type, "offtarget", "correct type" );
+ assert.equal( event.target, undefined, "no target" );
+} );
+
QUnit.test( "preventDefault() on focusin does not throw exception", function( assert ) {
assert.expect( 1 );
@@ -2770,6 +2799,81 @@ QUnit.test( "Donor event interference", function( assert ) {
jQuery( "#donor-input" )[ 0 ].click();
} );
+QUnit.test(
+ "native stop(Immediate)Propagation/preventDefault methods shouldn't be called",
+ function( assert ) {
+ var userAgent = window.navigator.userAgent;
+
+ if ( !( /firefox/i.test( userAgent ) || /safari/i.test( userAgent ) ) ) {
+ assert.expect( 1 );
+ assert.ok( true, "Assertions should run only in Chrome, Safari, Fx & Edge" );
+ return;
+ }
+
+ assert.expect( 3 );
+
+ var checker = {};
+
+ var html = "<div id='donor-outer'>" +
+ "<form id='donor-form'>" +
+ "<input id='donor-input' type='radio' />" +
+ "</form>" +
+ "</div>";
+
+ jQuery( "#qunit-fixture" ).append( html );
+ var outer = jQuery( "#donor-outer" );
+
+ outer
+ .on( "focusin", function( event ) {
+ checker.prevent = sinon.stub( event.originalEvent, "preventDefault" );
+ event.preventDefault();
+ } )
+ .on( "focusin", function( event ) {
+ checker.simple = sinon.stub( event.originalEvent, "stopPropagation" );
+ event.stopPropagation();
+ } )
+ .on( "focusin", function( event ) {
+ checker.immediate = sinon.stub( event.originalEvent, "stopImmediatePropagation" );
+ event.stopImmediatePropagation();
+ } );
+
+ jQuery( "#donor-input" ).trigger( "focus" );
+ assert.strictEqual( checker.simple.called, false );
+ assert.strictEqual( checker.immediate.called, false );
+ assert.strictEqual( checker.prevent.called, false );
+
+ // We need to "off" it, since yes QUnit always update the fixtures
+ // but "focus" event listener is attached to document for focus(in | out)
+ // event and document doesn't get cleared obviously :)
+ outer.off( "focusin" );
+ }
+);
+
+QUnit.test(
+ "isSimulated property always exist on event object",
+ function( assert ) {
+ var userAgent = window.navigator.userAgent;
+
+ if ( !( /firefox/i.test( userAgent ) || /safari/i.test( userAgent ) ) ) {
+ assert.expect( 1 );
+ assert.ok( true, "Assertions should run only in Chrome, Safari, Fx & Edge" );
+ return;
+ }
+
+ assert.expect( 1 );
+
+ var element = jQuery( "<input/>" );
+
+ jQuery( "#qunit-fixture" ).append( element );
+
+ element.on( "focus", function( event ) {
+ assert.notOk( event.isSimulated );
+ } );
+
+ element.trigger( "focus" );
+ }
+);
+
QUnit.test( "originalEvent property for Chrome, Safari, Fx & Edge of simulated event", function( assert ) {
var userAgent = window.navigator.userAgent;
@@ -2780,6 +2884,7 @@ QUnit.test( "originalEvent property for Chrome, Safari, Fx & Edge of simulated e
}
assert.expect( 4 );
+ var done = assert.async();
var html = "<div id='donor-outer'>" +
"<form id='donor-form'>" +
@@ -2788,19 +2893,27 @@ QUnit.test( "originalEvent property for Chrome, Safari, Fx & Edge of simulated e
"</div>";
jQuery( "#qunit-fixture" ).append( html );
+ var outer = jQuery( "#donor-outer" );
+
+ outer
+ .on( "focusin", function( event ) {
+ assert.ok( true, "focusin bubbled to outer div" );
+ assert.equal( event.originalEvent.type, "focus",
+ "make sure originalEvent type is correct" );
+ assert.equal( event.type, "focusin", "make sure type is correct" );
+ } );
- jQuery( "#donor-outer" ).on( "focusin", function( event ) {
- assert.ok( true, "focusin bubbled to outer div" );
- assert.equal( event.originalEvent.type, "focus",
- "make sure originalEvent type is correct" );
- assert.equal( event.type, "focusin", "make sure type is correct" );
- } );
jQuery( "#donor-input" ).on( "focus", function() {
assert.ok( true, "got a focus event from the input" );
+ done();
} );
jQuery( "#donor-input" ).trigger( "focus" );
-} );
+ // We need to "off" it, since yes QUnit always update the fixtures
+ // but "focus" event listener is attached to document for focus(in | out)
+ // event and document doesn't get cleared obviously :)
+ outer.off( "focusin" );
+} );
QUnit[ jQuery.fn.click ? "test" : "skip" ]( "trigger() shortcuts", function( assert ) {
assert.expect( 5 );
@@ -2854,7 +2967,7 @@ QUnit[ jQuery.fn.click ? "test" : "skip" ]( "Event aliases", function( assert )
} );
} );
-// Support: IE9 (remove when IE9 is no longer supported)
+// Support: IE <=9 only
// https://msdn.microsoft.com/en-us/library/hh801223(v=vs.85).aspx
QUnit.test( "VML with special event handlers (trac-7071)", function( assert ) {
assert.expect( 1 );
@@ -2907,6 +3020,7 @@ if ( !( /firefox/i.test( window.navigator.userAgent ) ) ) {
$text = jQuery( "#text1" ),
$radio = jQuery( "#radio1" ).trigger( "focus" );
+ // Support: IE <=10 only
// IE8-10 fire focus/blur events asynchronously; this is the resulting mess.
// IE's browser window must be topmost for this to work properly!!
QUnit.stop();
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index 1346cc0..9118524 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -406,8 +406,7 @@ QUnit.test( "XML DOM manipulation (#9960)", function( assert ) {
assert.expect( 5 );
- var scxml1Adopted,
- xmlDoc1 = jQuery.parseXML( "<scxml xmlns='http://www.w3.org/2005/07/scxml' version='1.0'><state x='100' y='100' initial='actions' id='provisioning'></state><state x='100' y='100' id='error'></state><state x='100' y='100' id='finished' final='true'></state></scxml>" ),
+ var xmlDoc1 = jQuery.parseXML( "<scxml xmlns='http://www.w3.org/2005/07/scxml' version='1.0'><state x='100' y='100' initial='actions' id='provisioning'></state><state x='100' y='100' id='error'></state><state x='100' y='100' id='finished' final='true'></state></scxml>" ),
xmlDoc2 = jQuery.parseXML( "<scxml xmlns='http://www.w3.org/2005/07/scxml' version='1.0'><state id='provisioning3'></state></scxml>" ),
xml1 = jQuery( xmlDoc1 ),
xml2 = jQuery( xmlDoc2 ),
@@ -415,15 +414,6 @@ QUnit.test( "XML DOM manipulation (#9960)", function( assert ) {
scxml2 = jQuery( "scxml", xml2 ),
state = scxml2.find( "state" );
- // Android 2.3 doesn't automatically adopt nodes from foreign documents.
- // Although technically this is compliant behavior, no other browser
- // (including newer Android Browsers) behave in this way so do the adopting
- // just for Android 2.3.
- // Support: Android 2.3
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- state = jQuery( xmlDoc1.adoptNode( state[ 0 ] ) );
- }
-
scxml1.append( state );
assert.strictEqual( scxml1[ 0 ].lastChild, state[ 0 ], "append" );
@@ -436,13 +426,7 @@ QUnit.test( "XML DOM manipulation (#9960)", function( assert ) {
scxml1.find( "#provisioning" ).before( state );
assert.strictEqual( scxml1[ 0 ].firstChild, state[ 0 ], "before" );
- // Support: Android 2.3
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- scxml1Adopted = jQuery( xmlDoc2.adoptNode( scxml1[ 0 ] ) );
- scxml2.replaceWith( scxml1Adopted );
- } else {
- scxml2.replaceWith( scxml1 );
- }
+ scxml2.replaceWith( scxml1 );
assert.deepEqual( jQuery( "state", xml2 ).get(), scxml1.find( "state" ).get(), "replaceWith" );
} );
@@ -527,6 +511,18 @@ QUnit.test( "Tag name processing respects the HTML Standard (gh-2005)", function
}
function assertSpecialCharsSupport( method, characters ) {
+ // Support: Android 4.4 only
+ // Chromium < 35 incorrectly upper-cases µ; Android 4.4 uses such a version by default
+ // (and its WebView, being un-updatable, will use it for eternity) so we need to blacklist
+ // that one for the tests to pass.
+ if ( characters === "µ" && /chrome/i.test( navigator.userAgent ) &&
+ navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ] < 35 ) {
+ assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" );
+ assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" );
+ assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" );
+ return;
+ }
+
var child,
codepoint = characters.charCodeAt( 0 ).toString( 16 ).toUpperCase(),
description = characters.length === 1 ?
@@ -613,7 +609,7 @@ QUnit.test( "append(xml)", function( assert ) {
// IE
for ( n = 0, len = aActiveX.length; n < len; n++ ) {
try {
- elem = new ActiveXObject( aActiveX[ n ] );
+ elem = new window.ActiveXObject( aActiveX[ n ] );
return elem;
} catch ( _ ) {}
}
@@ -1179,7 +1175,7 @@ QUnit.test( ".after(disconnected node)", function( assert ) {
QUnit.test( "insertAfter(String)", function( assert ) {
- assert.expect( 1 ) ;
+ assert.expect( 1 );
var expected = "This is a normal link: Yahoobuga";
jQuery( "<b>buga</b>" ).insertAfter( "#yahoo" );
@@ -1215,7 +1211,7 @@ QUnit.test( "insertAfter(jQuery)", function( assert ) {
function testReplaceWith( val, assert ) {
- var tmp, y, child, child2, set, non_existent, $div,
+ var tmp, y, child, child2, set, nonExistent, $div,
expected = 29;
assert.expect( expected );
@@ -1299,8 +1295,8 @@ function testReplaceWith( val, assert ) {
assert.deepEqual( jQuery( ".pathological", "#qunit-fixture" ).get(), [],
"Replacement with following sibling (context removed)" );
- non_existent = jQuery( "#does-not-exist" ).replaceWith( val( "<b>should not throw an error</b>" ) );
- assert.equal( non_existent.length, 0, "Length of non existent element." );
+ nonExistent = jQuery( "#does-not-exist" ).replaceWith( val( "<b>should not throw an error</b>" ) );
+ assert.equal( nonExistent.length, 0, "Length of non existent element." );
$div = jQuery( "<div class='replacewith'></div>" ).appendTo( "#qunit-fixture" );
$div.replaceWith( val( "<div class='replacewith'></div><script>" +
@@ -1363,7 +1359,7 @@ QUnit.test( "Empty replaceWith (trac-13401; trac-13596; gh-2204)", function( ass
assert.strictEqual( $el.html(), "", "replaceWith(" + label + ")" );
$el.html( "<b/>" ).children().replaceWith( function() { return input; } );
assert.strictEqual( $el.html(), "", "replaceWith(function returning " + label + ")" );
- $el.html( "<i/>" ).children().replaceWith( function( i ) { i; return input; } );
+ $el.html( "<i/>" ).children().replaceWith( function( i ) { return input; } );
assert.strictEqual( $el.html(), "", "replaceWith(other function returning " + label + ")" );
$el.html( "<p/>" ).children().replaceWith( function( i ) {
return i ?
@@ -1627,7 +1623,7 @@ QUnit.test( "clone(multiple selected options) (Bug #8129)", function( assert ) {
var element = jQuery( "<select><option>Foo</option><option selected>Bar</option><option selected>Baz</option></select>" );
function getSelectedOptions( collection ) {
- return collection.find( "option" ).filter(function( option ) {
+ return collection.find( "option" ).filter( function( option ) {
return option.selected;
} );
}
@@ -2241,21 +2237,21 @@ QUnit.test( "domManip executes scripts containing html comments or CDATA (trac-9
].join( "\n" ) ).appendTo( "#qunit-fixture" );
} );
-testIframeWithCallback(
+testIframe(
"domManip tolerates window-valued document[0] in IE9/10 (trac-12266)",
"manipulation/iframe-denied.html",
- function( test, assert ) {
+ function( assert, jQuery, window, document, test ) {
assert.expect( 1 );
assert.ok( test.status, test.description );
}
);
-testIframeWithCallback(
+testIframe(
"domManip executes scripts in iframes in the iframes' context",
"manipulation/scripts-context.html",
- function( frameWindow, bodyElement, html, assert ) {
+ function( assert, framejQuery, frameWindow, frameDocument ) {
assert.expect( 2 );
- jQuery( bodyElement ).append( html );
+ jQuery( frameDocument.body ).append( "<script>window.scriptTest = true;<\x2fscript>" );
assert.ok( !window.scriptTest, "script executed in iframe context" );
assert.ok( frameWindow.scriptTest, "script executed in iframe context" );
}
@@ -2365,18 +2361,6 @@ QUnit.test( "Ensure oldIE creates a new set on appendTo (#8894)", function( asse
} );
QUnit.asyncTest( "html() - script exceptions bubble (#11743)", 2, function( assert ) {
-
- // Support: Android 2.3 only
- // Android 2.3 doesn't fire the window.onerror handler, just accept the reality there.
- if ( /android 2\.3/i.test( navigator.userAgent ) ) {
- assert.ok( true, "Test skipped, Android 2.3 doesn't fire window.onerror for " +
- "errors in dynamically included scripts" );
- assert.ok( true, "Test skipped, Android 2.3 doesn't fire window.onerror for " +
- "errors in dynamically included scripts" );
- QUnit.start();
- return;
- }
-
var onerror = window.onerror;
setTimeout( function() {
@@ -2480,7 +2464,7 @@ QUnit.test( "script evaluation (#11795)", function( assert ) {
if ( jQuery.ajax ) {
Globals.register( "testBar" );
jQuery( "#qunit-fixture" ).append( "<script src='" + url( "data/testbar.php" ) + "'/>" );
- assert.strictEqual( window[ "testBar" ], "bar", "Global script evaluation" );
+ assert.strictEqual( window.testBar, "bar", "Global script evaluation" );
} else {
assert.ok( true, "No jQuery.ajax" );
assert.ok( true, "No jQuery.ajax" );
@@ -2761,8 +2745,8 @@ QUnit.test( "Insert script with data-URI (gh-1887)", 1, function( assert ) {
jQuery( fixture ).append( "<script src=\"data:text/javascript,testFoo = 'foo';\"></script>" );
setTimeout( function() {
- if ( window[ "testSrcFoo" ] === "foo" ) {
- assert.strictEqual( window[ "testFoo" ], window[ "testSrcFoo" ], "data-URI script executed" );
+ if ( window.testSrcFoo === "foo" ) {
+ assert.strictEqual( window.testFoo, window.testSrcFoo, "data-URI script executed" );
} else {
assert.ok( true, "data-URI script is not supported by this environment" );
diff --git a/test/unit/offset.js b/test/unit/offset.js
index a0f253b..c0df5f1 100644
--- a/test/unit/offset.js
+++ b/test/unit/offset.js
@@ -35,13 +35,6 @@ QUnit.module( "offset", { setup: function() {
forceScroll.detach();
}, teardown: moduleTeardown } );
-/*
- Closure-compiler will roll static methods off of the jQuery object and so they will
- not be passed with the jQuery object across the windows. To differentiate this, the
- testIframe callbacks use the "$" symbol to refer to the jQuery object passed from
- the iframe window and the "jQuery" symbol is used to access any static methods.
-*/
-
QUnit.test( "empty set", function( assert ) {
assert.expect( 2 );
assert.strictEqual( jQuery().offset(), undefined, "offset() returns undefined for empty set (#11962)" );
@@ -75,7 +68,7 @@ QUnit.test( "hidden (display: none) element", function( assert ) {
assert.equal( result.left, 0, "Retrieving offset on hidden elements returns zeros (gh-2310)" );
} );
-testIframe( "offset/absolute", "absolute", function( $, iframe, document, assert ) {
+testIframe( "absolute", "offset/absolute.html", function( assert, $, iframe ) {
assert.expect( 4 );
var doc = iframe.document,
@@ -86,8 +79,8 @@ testIframe( "offset/absolute", "absolute", function( $, iframe, document, assert
{ "id": "#absolute-1", "top": 1, "left": 1 }
];
jQuery.each( tests, function() {
- assert.equal( jQuery( this[ "id" ], doc ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset().top" );
- assert.equal( jQuery( this[ "id" ], doc ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset().left" );
+ assert.equal( jQuery( this.id, doc ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ assert.equal( jQuery( this.id, doc ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
} );
// get position
@@ -95,12 +88,12 @@ testIframe( "offset/absolute", "absolute", function( $, iframe, document, assert
{ "id": "#absolute-1", "top": 0, "left": 0 }
];
jQuery.each( tests, function() {
- assert.equal( jQuery( this[ "id" ], doc ).position().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').position().top" );
- assert.equal( jQuery( this[ "id" ], doc ).position().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').position().left" );
+ assert.equal( jQuery( this.id, doc ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
+ assert.equal( jQuery( this.id, doc ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
} );
} );
-testIframe( "offset/absolute", "absolute", function( $, window, document, assert ) {
+testIframe( "absolute", "offset/absolute.html", function( assert, $ ) {
assert.expect( 178 );
var tests, offset;
@@ -113,8 +106,8 @@ testIframe( "offset/absolute", "absolute", function( $, window, document, assert
{ "id": "#absolute-2", "top": 20, "left": 20 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset().top" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset().left" );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
} );
// get position
@@ -125,8 +118,8 @@ testIframe( "offset/absolute", "absolute", function( $, window, document, assert
{ "id": "#absolute-2", "top": 19, "left": 19 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).position().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').position().top" );
- assert.equal( $( this[ "id" ] ).position().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').position().left" );
+ assert.equal( $( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
+ assert.equal( $( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
} );
// test #5781
@@ -154,38 +147,38 @@ testIframe( "offset/absolute", "absolute", function( $, window, document, assert
{ "id": "#absolute-1", "top": 1, "left": 1 }
];
jQuery.each( tests, function() {
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ] } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset({ top: " + this[ "top" ] + " })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset({ left: " + this[ "left" ] + " })" );
+ $( this.id ).offset( { "top": this.top, "left": this.left } );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
- var top = this[ "top" ], left = this[ "left" ];
+ var top = this.top, left = this.left;
- $( this[ "id" ] ).offset( function( i, val ) {
+ $( this.id ).offset( function( i, val ) {
assert.equal( val.top, top, "Verify incoming top position." );
assert.equal( val.left, left, "Verify incoming top position." );
return { "top": top + 1, "left": left + 1 };
} );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ top: " + ( this[ "top" ] + 1 ) + " })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ left: " + ( this[ "left" ] + 1 ) + " })" );
+ assert.equal( $( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + ( this.top + 1 ) + " })" );
+ assert.equal( $( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + ( this.left + 1 ) + " })" );
- $( this[ "id" ] )
- .offset( { "left": this[ "left" ] + 2 } )
- .offset( { "top": this[ "top" ] + 2 } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 2, "Setting one property at a time." );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 2, "Setting one property at a time." );
+ $( this.id )
+ .offset( { "left": this.left + 2 } )
+ .offset( { "top": this.top + 2 } );
+ assert.equal( $( this.id ).offset().top, this.top + 2, "Setting one property at a time." );
+ assert.equal( $( this.id ).offset().left, this.left + 2, "Setting one property at a time." );
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ], "using": function( props ) {
+ $( this.id ).offset( { "top": this.top, "left": this.left, "using": function( props ) {
$( this ).css( {
"top": props.top + 1,
"left": props.left + 1
} );
} } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ top: " + ( this[ "top" ] + 1 ) + ", using: fn })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ left: " + ( this[ "left" ] + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + ( this.top + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + ( this.left + 1 ) + ", using: fn })" );
} );
} );
-testIframe( "offset/relative", "relative", function( $, window, document, assert ) {
+testIframe( "relative", "offset/relative.html", function( assert, $ ) {
assert.expect( 64 );
// get offset
@@ -196,8 +189,8 @@ testIframe( "offset/relative", "relative", function( $, window, document, assert
{ "id": "#relative-2-1", "top": 149, "left": 52 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset().top" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset().left" );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
} );
// get position
@@ -208,8 +201,8 @@ testIframe( "offset/relative", "relative", function( $, window, document, assert
{ "id": "#relative-2-1", "top": 5, "left": 5 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).position().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').position().top" );
- assert.equal( $( this[ "id" ] ).position().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').position().left" );
+ assert.equal( $( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
+ assert.equal( $( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
} );
// set offset
@@ -228,22 +221,22 @@ testIframe( "offset/relative", "relative", function( $, window, document, assert
{ "id": "#relative-1", "top": 7, "left": 7 }
];
jQuery.each( tests, function() {
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ] } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset({ top: " + this[ "top" ] + " })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset({ left: " + this[ "left" ] + " })" );
+ $( this.id ).offset( { "top": this.top, "left": this.left } );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ], "using": function( props ) {
+ $( this.id ).offset( { "top": this.top, "left": this.left, "using": function( props ) {
$( this ).css( {
"top": props.top + 1,
"left": props.left + 1
} );
} } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ top: " + ( this[ "top" ] + 1 ) + ", using: fn })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ left: " + ( this[ "left" ] + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + ( this.top + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + ( this.left + 1 ) + ", using: fn })" );
} );
} );
-testIframe( "offset/static", "static", function( $, window, document, assert ) {
+testIframe( "static", "offset/static.html", function( assert, $ ) {
assert.expect( 80 );
// get offset
@@ -254,8 +247,8 @@ testIframe( "offset/static", "static", function( $, window, document, assert ) {
{ "id": "#static-2", "top": 122, left: 7 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset().top" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset().left" );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
} );
// get position
@@ -266,8 +259,8 @@ testIframe( "offset/static", "static", function( $, window, document, assert ) {
{ "id": "#static-2", "top": 121, "left": 6 }
];
jQuery.each( tests, function() {
- assert.equal( $( this[ "id" ] ).position().top, this[ "top" ], "jQuery('" + this[ "top" ] + "').position().top" );
- assert.equal( $( this[ "id" ] ).position().left, this[ "left" ], "jQuery('" + this[ "left" ] + "').position().left" );
+ assert.equal( $( this.id ).position().top, this.top, "jQuery('" + this.top + "').position().top" );
+ assert.equal( $( this.id ).position().left, this.left, "jQuery('" + this.left + "').position().left" );
} );
// set offset
@@ -290,22 +283,22 @@ testIframe( "offset/static", "static", function( $, window, document, assert ) {
{ "id": "#static-1", "top": 7, "left": 7 }
];
jQuery.each( tests, function() {
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ] } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset({ top: " + this[ "top" ] + " })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset({ left: " + this[ "left" ] + " })" );
+ $( this.id ).offset( { "top": this.top, "left": this.left } );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ], "using": function( props ) {
+ $( this.id ).offset( { "top": this.top, "left": this.left, "using": function( props ) {
$( this ).css( {
"top": props.top + 1,
"left": props.left + 1
} );
} } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ top: " + ( this[ "top" ] + 1 ) + ", using: fn })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ left: " + ( this[ "left" ] + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + ( this.top + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + ( this.left + 1 ) + ", using: fn })" );
} );
} );
-testIframe( "offset/fixed", "fixed", function( $, window, document, assert ) {
+testIframe( "fixed", "offset/fixed.html", function( assert, $, window ) {
assert.expect( 34 );
var tests, $noTopLeft;
@@ -335,10 +328,10 @@ testIframe( "offset/fixed", "fixed", function( $, window, document, assert ) {
assert.ok( true, "Browser doesn't support scroll position." );
} else if ( window.supportsFixedPosition ) {
- assert.equal( $( this[ "id" ] ).offset().top, this[ "offsetTop" ], "jQuery('" + this[ "id" ] + "').offset().top" );
- assert.equal( $( this[ "id" ] ).position().top, this[ "positionTop" ], "jQuery('" + this[ "id" ] + "').position().top" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "offsetLeft" ], "jQuery('" + this[ "id" ] + "').offset().left" );
- assert.equal( $( this[ "id" ] ).position().left, this[ "positionLeft" ], "jQuery('" + this[ "id" ] + "').position().left" );
+ assert.equal( $( this.id ).offset().top, this.offsetTop, "jQuery('" + this.id + "').offset().top" );
+ assert.equal( $( this.id ).position().top, this.positionTop, "jQuery('" + this.id + "').position().top" );
+ assert.equal( $( this.id ).offset().left, this.offsetLeft, "jQuery('" + this.id + "').offset().left" );
+ assert.equal( $( this.id ).position().left, this.positionLeft, "jQuery('" + this.id + "').position().left" );
} else {
// need to have same number of assertions
@@ -360,18 +353,18 @@ testIframe( "offset/fixed", "fixed", function( $, window, document, assert ) {
jQuery.each( tests, function() {
if ( window.supportsFixedPosition ) {
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ] } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ], "jQuery('" + this[ "id" ] + "').offset({ top: " + this[ "top" ] + " })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ], "jQuery('" + this[ "id" ] + "').offset({ left: " + this[ "left" ] + " })" );
+ $( this.id ).offset( { "top": this.top, "left": this.left } );
+ assert.equal( $( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ assert.equal( $( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
- $( this[ "id" ] ).offset( { "top": this[ "top" ], "left": this[ "left" ], "using": function( props ) {
+ $( this.id ).offset( { "top": this.top, "left": this.left, "using": function( props ) {
$( this ).css( {
"top": props.top + 1,
"left": props.left + 1
} );
} } );
- assert.equal( $( this[ "id" ] ).offset().top, this[ "top" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ top: " + ( this[ "top" ] + 1 ) + ", using: fn })" );
- assert.equal( $( this[ "id" ] ).offset().left, this[ "left" ] + 1, "jQuery('" + this[ "id" ] + "').offset({ left: " + ( this[ "left" ] + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + ( this.top + 1 ) + ", using: fn })" );
+ assert.equal( $( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + ( this.left + 1 ) + ", using: fn })" );
} else {
// need to have same number of assertions
@@ -395,7 +388,7 @@ testIframe( "offset/fixed", "fixed", function( $, window, document, assert ) {
}
} );
-testIframe( "offset/table", "table", function( $, window, document, assert ) {
+testIframe( "table", "offset/table.html", function( assert, $ ) {
assert.expect( 4 );
assert.equal( $( "#table-1" ).offset().top, 6, "jQuery('#table-1').offset().top" );
@@ -405,8 +398,8 @@ testIframe( "offset/table", "table", function( $, window, document, assert ) {
assert.equal( $( "#th-1" ).offset().left, 10, "jQuery('#th-1').offset().left" );
} );
-testIframe( "offset/scroll", "scroll", function( $, win, doc, assert ) {
- assert.expect( 30 );
+testIframe( "scroll", "offset/scroll.html", function( assert, $, win ) {
+ assert.expect( 26 );
assert.equal( $( "#scroll-1" ).offset().top, 7, "jQuery('#scroll-1').offset().top" );
assert.equal( $( "#scroll-1" ).offset().left, 7, "jQuery('#scroll-1').offset().left" );
@@ -462,20 +455,9 @@ testIframe( "offset/scroll", "scroll", function( $, win, doc, assert ) {
assert.notEqual( $().scrollLeft( null ), null, "jQuery().scrollLeft(null) testing setter on empty jquery object" );
assert.strictEqual( $().scrollTop(), undefined, "jQuery().scrollTop() testing getter on empty jquery object" );
assert.strictEqual( $().scrollLeft(), undefined, "jQuery().scrollLeft() testing getter on empty jquery object" );
-
- // Tests position after parent scrolling (#15239)
- $( "#scroll-1" ).scrollTop( 0 );
- $( "#scroll-1" ).scrollLeft( 0 );
- assert.equal( $( "#scroll-1-1" ).position().top, 6, "jQuery('#scroll-1-1').position().top unaffected by parent scrolling" );
- assert.equal( $( "#scroll-1-1" ).position().left, 6, "jQuery('#scroll-1-1').position().left unaffected by parent scrolling" );
-
- $( "#scroll-1" ).scrollTop( 5 );
- $( "#scroll-1" ).scrollLeft( 5 );
- assert.equal( $( "#scroll-1-1" ).position().top, 6, "jQuery('#scroll-1-1').position().top unaffected by parent scrolling" );
- assert.equal( $( "#scroll-1-1" ).position().left, 6, "jQuery('#scroll-1-1').position().left unaffected by parent scrolling" );
} );
-testIframe( "offset/body", "body", function( $, window, document, assert ) {
+testIframe( "body", "offset/body.html", function( assert, $ ) {
assert.expect( 4 );
assert.equal( $( "body" ).offset().top, 1, "jQuery('#body').offset().top" );
@@ -486,6 +468,7 @@ testIframe( "offset/body", "body", function( $, window, document, assert ) {
QUnit.test( "chaining", function( assert ) {
assert.expect( 3 );
+
var coords = { "top": 1, "left": 1 };
assert.equal( jQuery( "#absolute-1" ).offset( coords ).jquery, jQuery.fn.jquery, "offset(coords) returns jQuery object" );
assert.equal( jQuery( "#non-existent" ).offset( coords ).jquery, jQuery.fn.jquery, "offset(coords) with empty jQuery set returns jQuery object" );
@@ -550,7 +533,7 @@ QUnit.test( "fractions (see #7730 and #7885)", function( assert ) {
result = div.offset();
- // Support: Chrome 45-46+
+ // Support: Chrome <=45 - 46
// In recent Chrome these values differ a little.
assert.ok( Math.abs( result.top - expected.top ) < 0.25, "Check top within 0.25 of expected" );
assert.equal( result.left, expected.left, "Check left" );
@@ -563,12 +546,13 @@ QUnit.test( "iframe scrollTop/Left (see gh-1945)", function( assert ) {
var ifDoc = jQuery( "#iframe" )[ 0 ].contentDocument;
- // Mobile Safari and Android 2.3 resize the iframe by its content
- // meaning it's not possible to scroll the iframe only its parent element.
+ // Mobile Safari resize the iframe by its content meaning it's not possible to scroll
+ // the iframe but only its parent element.
// It seems (not confirmed) in android 4.0 it's not possible to scroll iframes from the code.
- if ( /iphone os/i.test( navigator.userAgent ) ||
- /android 2\.3/i.test( navigator.userAgent ) ||
- /android 4\.0/i.test( navigator.userAgent ) ) {
+ if (
+ /iphone os/i.test( navigator.userAgent ) ||
+ /android 4\.0/i.test( navigator.userAgent )
+ ) {
assert.equal( true, true, "Can't scroll iframes in this environment" );
assert.equal( true, true, "Can't scroll iframes in this environment" );
diff --git a/test/unit/queue.js b/test/unit/queue.js
index fa8b671..2248c68 100644
--- a/test/unit/queue.js
+++ b/test/unit/queue.js
@@ -232,7 +232,7 @@ QUnit.asyncTest( "fn.promise( \"queue\" ) - called whenever last queue function
} );
if ( jQuery.fn.animate ) {
-
+
QUnit.asyncTest( "fn.promise( \"queue\" ) - waits for animation to complete before resolving", 2, function( assert ) {
var foo = jQuery( "#foo" ),
test = 1;
diff --git a/test/unit/ready.js b/test/unit/ready.js
index 6272dbd..775b604 100644
--- a/test/unit/ready.js
+++ b/test/unit/ready.js
@@ -2,6 +2,8 @@ QUnit.module( "ready" );
( function() {
var notYetReady, noEarlyExecution,
+ whenified = jQuery.when( jQuery.ready ),
+ promisified = Promise.resolve( jQuery.ready ),
order = [],
args = {};
@@ -26,26 +28,47 @@ QUnit.module( "ready" );
};
}
+ function throwError( num ) {
+
+ // Not a global QUnit failure
+ var onerror = window.onerror;
+ window.onerror = function() {
+ window.onerror = onerror;
+ };
+
+ throw new Error( "Ready error " + num );
+ }
+
// Bind to the ready event in every possible way.
jQuery( makeHandler( "a" ) );
jQuery( document ).ready( makeHandler( "b" ) );
+ jQuery.ready.then( makeHandler( "c" ) );
+
+ // Throw in some errors
+ jQuery( function() {
+ throwError( 1 );
+ } );
+ jQuery( function() {
+ throwError( 2 );
+ } );
- // Do it twice, just to be sure.
- jQuery( makeHandler( "c" ) );
- jQuery( document ).ready( makeHandler( "d" ) );
+ // Bind again to ensure that the errors didn't lock everything up
+ jQuery( makeHandler( "d" ) );
+ jQuery( document ).ready( makeHandler( "e" ) );
+ jQuery.ready.then( makeHandler( "f" ) );
noEarlyExecution = order.length === 0;
// This assumes that QUnit tests are run on DOM ready!
QUnit.test( "jQuery ready", function( assert ) {
- assert.expect( 8 );
+ assert.expect( 10 );
assert.ok( noEarlyExecution,
"Handlers bound to DOM ready should not execute before DOM ready" );
// Ensure execution order.
- assert.deepEqual( order, [ "a", "b", "c", "d" ],
- "Bound DOM ready handlers should execute in on-order" );
+ assert.deepEqual( order, [ "a", "b", "c", "d", "e", "f" ],
+ "Bound DOM ready handlers should execute in bind order" );
// Ensure handler argument is correct.
assert.equal( args.a, jQuery,
@@ -55,16 +78,73 @@ QUnit.module( "ready" );
order = [];
- // Now that the ready event has fired, again bind to the ready event
- // in every possible way. These event handlers should execute immediately.
+ // Now that the ready event has fired, again bind to the ready event.
+ // These ready handlers should execute asynchronously.
+ var done = assert.async();
jQuery( makeHandler( "g" ) );
- assert.equal( order.pop(), "g", "Event handler should execute immediately" );
- assert.equal( args.g, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery" );
-
jQuery( document ).ready( makeHandler( "h" ) );
- assert.equal( order.pop(), "h", "Event handler should execute immediately" );
- assert.equal( args.h, jQuery,
- "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery" );
+ jQuery.ready.then( makeHandler( "i" ) );
+ window.setTimeout( function() {
+ assert.equal( order.shift(), "g",
+ "Event handler should execute immediately, but async" );
+ assert.equal( args.g, jQuery,
+ "Argument passed to fn in jQuery( fn ) should be jQuery" );
+
+ assert.equal( order.shift(), "h",
+ "Event handler should execute immediately, but async" );
+ assert.equal( args.h, jQuery,
+ "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery" );
+
+ assert.equal( order.shift(), "i",
+ "Event handler should execute immediately, but async" );
+ assert.equal( args.h, jQuery,
+ "Argument passed to fn in jQuery.ready.then( fn ) should be jQuery" );
+
+ done();
+ } );
} );
+ QUnit.test( "jQuery.when(jQuery.ready)", function( assert ) {
+ assert.expect( 2 );
+ var done = jQuery.map( new Array( 2 ), function() { return assert.async(); } );
+
+ whenified.then( function() {
+ assert.ok( jQuery.isReady, "jQuery.when Deferred resolved" );
+ done.pop()();
+ } );
+
+ jQuery.when( jQuery.ready ).then( function() {
+ assert.ok( jQuery.isReady, "jQuery.when Deferred resolved" );
+ done.pop()();
+ } );
+ } );
+
+ QUnit.test( "Promise.resolve(jQuery.ready)", function( assert ) {
+ assert.expect( 2 );
+ var done = jQuery.map( new Array( 2 ), function() { return assert.async(); } );
+
+ promisified.then( function() {
+ assert.ok( jQuery.isReady, "Native promised resolved" );
+ done.pop()();
+ } );
+
+ Promise.resolve( jQuery.ready ).then( function() {
+ assert.ok( jQuery.isReady, "Native promised resolved" );
+ done.pop()();
+ } );
+ } );
+
+ QUnit.test( "Error in ready callback does not halt all future executions (gh-1823)", function( assert ) {
+ assert.expect( 1 );
+ var done = assert.async();
+
+ jQuery( function() {
+ throwError( 3 );
+ } );
+
+ jQuery( function() {
+ assert.ok( true, "Subsequent handler called" );
+ done();
+ } );
+ } );
} )();
diff --git a/test/unit/selector.js b/test/unit/selector.js
index 2f6e9af..0177f4b 100644
--- a/test/unit/selector.js
+++ b/test/unit/selector.js
@@ -32,7 +32,7 @@ QUnit.test( "id", function( assert ) {
assert.t( "ID selector with existing ID descendant", "#firstp #simon1", [ "simon1" ] );
assert.t( "ID selector with non-existent descendant", "#firstp #foobar", [] );
assert.t( "ID selector using UTF8", "#台北Táiběi", [ "台北Táiběi" ] );
- assert.t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", [ "台北Táiběi","台北" ] );
+ assert.t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", [ "台北Táiběi", "台北" ] );
assert.t( "Descendant ID selector using UTF8", "div #台北", [ "台北" ] );
assert.t( "Child ID selector using UTF8", "form > #台北", [ "台北" ] );
@@ -103,14 +103,14 @@ QUnit.test( "selectors with comma", function( assert ) {
QUnit.test( "child and adjacent", function( assert ) {
assert.expect( 27 );
- assert.t( "Child", "p > a", [ "simon1","google","groups","mark","yahoo","simon" ] );
- assert.t( "Child", "p> a", [ "simon1","google","groups","mark","yahoo","simon" ] );
- assert.t( "Child", "p >a", [ "simon1","google","groups","mark","yahoo","simon" ] );
- assert.t( "Child", "p>a", [ "simon1","google","groups","mark","yahoo","simon" ] );
- assert.t( "Child w/ Class", "p > a.blog", [ "mark","simon" ] );
- assert.t( "All Children", "code > *", [ "anchor1","anchor2" ] );
- assert.t( "All Grandchildren", "p > * > *", [ "anchor1","anchor2" ] );
- assert.t( "Adjacent", "p + p", [ "ap","en","sap" ] );
+ assert.t( "Child", "p > a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
+ assert.t( "Child", "p> a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
+ assert.t( "Child", "p >a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
+ assert.t( "Child", "p>a", [ "simon1", "google", "groups", "mark", "yahoo", "simon" ] );
+ assert.t( "Child w/ Class", "p > a.blog", [ "mark", "simon" ] );
+ assert.t( "All Children", "code > *", [ "anchor1", "anchor2" ] );
+ assert.selectInFixture( "All Grandchildren", "p > * > *", [ "anchor1", "anchor2" ] );
+ assert.t( "Adjacent", "p + p", [ "ap", "en", "sap" ] );
assert.t( "Adjacent", "p#firstp + p", [ "ap" ] );
assert.t( "Adjacent", "p[lang=en] + p", [ "sap" ] );
assert.t( "Adjacent", "a.GROUPS + code + a", [ "mark" ] );
@@ -163,7 +163,7 @@ QUnit.test( "attributes", function( assert ) {
assert.t( "Attribute Equals", "#qunit-fixture a[rel=bookmark]", [ "simon1" ] );
assert.t( "Attribute Equals", "#qunit-fixture a[href='http://www.google.com/']", [ "google" ] );
assert.t( "Attribute Equals", "#qunit-fixture a[ rel = 'bookmark' ]", [ "simon1" ] );
- assert.t( "Attribute Equals Number", "#qunit-fixture option[value='1']", [ "option1b","option2b","option3b","option4b","option5c" ] );
+ assert.t( "Attribute Equals Number", "#qunit-fixture option[value='1']", [ "option1b", "option2b", "option3b", "option4b", "option5c" ] );
assert.t( "Attribute Equals Number", "#qunit-fixture li[tabIndex='-1']", [ "foodWithNegativeTabIndex" ] );
document.getElementById( "anchor2" ).href = "#2";
@@ -187,13 +187,13 @@ QUnit.test( "attributes", function( assert ) {
assert.t( "Attribute selector using UTF8", "span[lang=中文]", [ "台北" ] );
- assert.t( "Attribute Begins With", "a[href ^= 'http://www']", [ "google","yahoo" ] );
+ assert.t( "Attribute Begins With", "a[href ^= 'http://www']", [ "google", "yahoo" ] );
assert.t( "Attribute Ends With", "a[href $= 'org/']", [ "mark" ] );
- assert.t( "Attribute Contains", "a[href *= 'google']", [ "google","groups" ] );
+ assert.t( "Attribute Contains", "a[href *= 'google']", [ "google", "groups" ] );
if ( jQuery.find.compile ) {
- assert.t( "Empty values", "#select1 option[value!='']", [ "option1b","option1c","option1d" ] );
- assert.t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", [ "google","groups","anchor1" ] );
+ assert.t( "Empty values", "#select1 option[value!='']", [ "option1b", "option1c", "option1d" ] );
+ assert.t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", [ "google", "groups", "anchor1" ] );
assert.t( "Select options via :selected", "#select1 option:selected", [ "option1a" ] );
assert.t( "Select options via :selected", "#select2 option:selected", [ "option2d" ] );
assert.t( "Select options via :selected", "#select3 option:selected", [ "option3b", "option3c" ] );
@@ -290,9 +290,9 @@ QUnit[ jQuery.find.compile ? "test" : "skip" ]( "disconnected nodes", function(
} );
testIframe(
- "selector/html5_selector",
"attributes - jQuery.attr",
- function( jQuery, window, document, assert ) {
+ "selector/html5_selector.html",
+ function( assert, jQuery, window, document ) {
assert.expect( 38 );
/**
@@ -490,10 +490,10 @@ QUnit.test( "jQuery.uniqueSort", function( assert ) {
} );
testIframe(
- "selector/sizzle_cache",
"Sizzle cache collides with multiple Sizzles on a page",
- function( jQuery, window, document, assert ) {
- var $cached = window[ "$cached" ];
+ "selector/sizzle_cache.html",
+ function( assert, jQuery, window, document ) {
+ var $cached = window.$cached;
assert.expect( 4 );
assert.notStrictEqual( jQuery, $cached, "Loaded two engines" );
@@ -536,3 +536,9 @@ QUnit.asyncTest( "Iframe dispatch should not affect jQuery (#13936)", 1, functio
iframeDoc.write( "<body><form id='navigate' action='?'></form></body>" );
iframeDoc.close();
} );
+
+QUnit.test( "Ensure escapeSelector exists (escape tests in Sizzle)", function( assert ) {
+ assert.expect( 1 );
+
+ assert.equal( jQuery.escapeSelector( "#foo.bar" ), "\\#foo\\.bar", "escapeSelector present" );
+} );
diff --git a/test/unit/serialize.js b/test/unit/serialize.js
index 65d9417..9d0afd7 100644
--- a/test/unit/serialize.js
+++ b/test/unit/serialize.js
@@ -3,14 +3,12 @@ QUnit.module( "serialize", { teardown: moduleTeardown } );
QUnit.test( "jQuery.param()", function( assert ) {
assert.expect( 23 );
- var params, settings;
-
- assert.equal( !( jQuery.ajaxSettings && jQuery.ajaxSettings.traditional ), true, "traditional flag, falsy by default" );
+ var params;
params = { "foo":"bar", "baz":42, "quux":"All your base are belong to us" };
assert.equal( jQuery.param( params ), "foo=bar&baz=42&quux=All%20your%20base%20are%20belong%20to%20us", "simple" );
- params = { "string":"foo","null":null,"undefined":undefined };
+ params = { "string":"foo", "null":null, "undefined":undefined };
assert.equal( jQuery.param( params ), "string=foo&null=&undefined=", "handle nulls and undefineds properly" );
params = { "someName": [ 1, 2, 3 ], "regularThing": "blah" };
@@ -25,66 +23,68 @@ QUnit.test( "jQuery.param()", function( assert ) {
params = { "foo": { "bar": "baz", "beep": 42, "quux": "All your base are belong to us" } };
assert.equal( jQuery.param( params ), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All%20your%20base%20are%20belong%20to%20us", "even more arrays" );
- params = { a:[ 1,2 ], b:{ c:3, d:[ 4,5 ], e:{ x:[ 6 ], y:7, z:[ 8,9 ] }, f:true, g:false, h:undefined }, i:[ 10,11 ], j:true, k:false, l:[ undefined,0 ], m:"cowboy hat?" };
+ params = { a:[ 1, 2 ], b:{ c:3, d:[ 4, 5 ], e:{ x:[ 6 ], y:7, z:[ 8, 9 ] }, f:true, g:false, h:undefined }, i:[ 10, 11 ], j:true, k:false, l:[ undefined, 0 ], m:"cowboy hat?" };
assert.equal( decodeURIComponent( jQuery.param( params ) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy hat?", "huge structure" );
params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, "d": 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
assert.equal( decodeURIComponent( jQuery.param( params ) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
- params = { "a":[ 1,2 ], "b":{ "c":3, "d":[ 4,5 ], "e":{ "x":[ 6 ], "y":7, "z":[ 8,9 ] }, "f":true, "g":false, "h":undefined }, "i":[ 10,11 ], "j":true, "k":false, "l":[ undefined,0 ], "m":"cowboy hat?" };
+ params = { "a":[ 1, 2 ], "b":{ "c":3, "d":[ 4, 5 ], "e":{ "x":[ 6 ], "y":7, "z":[ 8, 9 ] }, "f":true, "g":false, "h":undefined }, "i":[ 10, 11 ], "j":true, "k":false, "l":[ undefined, 0 ], "m":"cowboy hat?" };
assert.equal( jQuery.param( params, true ), "a=1&a=2&b=%5Bobject%20Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy%20hat%3F", "huge structure, forced traditional" );
- assert.equal( decodeURIComponent( jQuery.param( { "a": [ 1,2,3 ], "b[]": [ 4,5,6 ], "c[d]": [ 7,8,9 ], "e": { "f": [ 10 ], "g": [ 11,12 ], "h": 13 } } ) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
+ assert.equal( decodeURIComponent( jQuery.param( { "a": [ 1, 2, 3 ], "b[]": [ 4, 5, 6 ], "c[d]": [ 7, 8, 9 ], "e": { "f": [ 10 ], "g": [ 11, 12 ], "h": 13 } } ) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." );
// #7945
assert.equal( jQuery.param( { "jquery": "1.4.2" } ), "jquery=1.4.2", "Check that object with a jQuery property get serialized correctly" );
- settings = { traditional: true };
-
- if ( jQuery.ajaxSettings ) {
- jQuery.ajaxSetup( settings );
- } else {
- jQuery.ajaxSettings = settings;
- }
-
params = { "foo":"bar", "baz":42, "quux":"All your base are belong to us" };
- assert.equal( jQuery.param( params ), "foo=bar&baz=42&quux=All%20your%20base%20are%20belong%20to%20us", "simple" );
+ assert.equal( jQuery.param( params, true ), "foo=bar&baz=42&quux=All%20your%20base%20are%20belong%20to%20us", "simple" );
params = { "someName": [ 1, 2, 3 ], "regularThing": "blah" };
- assert.equal( jQuery.param( params ), "someName=1&someName=2&someName=3®ularThing=blah", "with array" );
+ assert.equal( jQuery.param( params, true ), "someName=1&someName=2&someName=3®ularThing=blah", "with array" );
params = { "foo": [ "a", "b", "c" ] };
- assert.equal( jQuery.param( params ), "foo=a&foo=b&foo=c", "with array of strings" );
+ assert.equal( jQuery.param( params, true ), "foo=a&foo=b&foo=c", "with array of strings" );
params = { "foo[]":[ "baz", 42, "All your base are belong to us" ] };
- assert.equal( jQuery.param( params ), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All%20your%20base%20are%20belong%20to%20us", "more array" );
+ assert.equal( jQuery.param( params, true ), "foo%5B%5D=baz&foo%5B%5D=42&foo%5B%5D=All%20your%20base%20are%20belong%20to%20us", "more array" );
params = { "foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us" };
- assert.equal( jQuery.param( params ), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All%20your%20base%20are%20belong%20to%20us", "even more arrays" );
+ assert.equal( jQuery.param( params, true ), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All%20your%20base%20are%20belong%20to%20us", "even more arrays" );
- params = { a:[ 1,2 ], b:{ c:3, d:[ 4,5 ], e:{ x:[ 6 ], y:7, z:[ 8,9 ] }, f:true, g:false, h:undefined }, i:[ 10,11 ], j:true, k:false, l:[ undefined,0 ], m:"cowboy hat?" };
- assert.equal( jQuery.param( params ), "a=1&a=2&b=%5Bobject%20Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy%20hat%3F", "huge structure" );
+ params = { a:[ 1, 2 ], b:{ c:3, d:[ 4, 5 ], e:{ x:[ 6 ], y:7, z:[ 8, 9 ] }, f:true, g:false, h:undefined }, i:[ 10, 11 ], j:true, k:false, l:[ undefined, 0 ], m:"cowboy hat?" };
+ assert.equal( jQuery.param( params, true ), "a=1&a=2&b=%5Bobject%20Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy%20hat%3F", "huge structure" );
params = { "a": [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { "b": [ 7, [ 8, 9 ], [ { "c": 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { "e": { "f": { "g": [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
- assert.equal( jQuery.param( params ), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject%20Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
+ assert.equal( jQuery.param( params, true ), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject%20Object%5D&a=17", "nested arrays (not possible when traditional == true)" );
- params = { a:[ 1,2 ], b:{ c:3, d:[ 4,5 ], e:{ x:[ 6 ], y:7, z:[ 8,9 ] }, f:true, g:false, h:undefined }, i:[ 10,11 ], j:true, k:false, l:[ undefined,0 ], m:"cowboy hat?" };
- assert.equal( decodeURIComponent( jQuery.param( params, false ) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy hat?", "huge structure, forced not traditional" );
+ params = { a:[ 1, 2 ], b:{ c:3, d:[ 4, 5 ], e:{ x:[ 6 ], y:7, z:[ 8, 9 ] }, f:true, g:false, h:undefined }, i:[ 10, 11 ], j:true, k:false, l:[ undefined, 0 ], m:"cowboy hat?" };
+ assert.equal( decodeURIComponent( jQuery.param( params ) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy hat?", "huge structure, forced not traditional" );
params = { "param1": null };
- assert.equal( jQuery.param( params, false ), "param1=", "Make sure that null params aren't traversed." );
+ assert.equal( jQuery.param( params ), "param1=", "Make sure that null params aren't traversed." );
+
+ params = { "param1": function() {}, "param2": function() { return null; } };
+ assert.equal( jQuery.param( params, false ), "param1=¶m2=", "object with function property that returns null value" );
params = { "test": { "length": 3, "foo": "bar" } };
- assert.equal( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" );
+ assert.equal( jQuery.param( params ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" );
params = { "test": [ 1, 2, null ] };
- assert.equal( jQuery.param( params, false ), "test%5B%5D=1&test%5B%5D=2&test%5B%5D=", "object with array property with null value" );
+ assert.equal( jQuery.param( params ), "test%5B%5D=1&test%5B%5D=2&test%5B%5D=", "object with array property with null value" );
+} );
- if ( jQuery.ajaxSettings === settings ) {
- delete jQuery.ajaxSettings;
- } else {
- jQuery.ajaxSetup( { traditional: false } );
- }
+QUnit.test( "jQuery.param() not affected by ajaxSettings", function( assert ) {
+ assert.expect( 1 );
+
+ var oldTraditional = jQuery.ajaxSettings.traditional;
+ jQuery.ajaxSettings.traditional = true;
+ assert.equal(
+ jQuery.param( { "foo": [ "a", "b", "c" ] } ),
+ "foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c",
+ "ajaxSettings.traditional is ignored"
+ );
+ jQuery.ajaxSettings.traditional = oldTraditional;
} );
QUnit.test( "jQuery.param() Constructed prop values", function( assert ) {
@@ -92,7 +92,7 @@ QUnit.test( "jQuery.param() Constructed prop values", function( assert ) {
/** @constructor */
function Record() {
- this[ "prop" ] = "val";
+ this.prop = "val";
}
var MyString = String,
diff --git a/test/unit/support.js b/test/unit/support.js
index 6a51ccb..5be7819 100644
--- a/test/unit/support.js
+++ b/test/unit/support.js
@@ -18,10 +18,10 @@ function getComputedSupport( support ) {
}
if ( jQuery.css ) {
- testIframeWithCallback(
+ testIframe(
"body background is not lost if set prior to loading jQuery (#9239)",
"support/bodyBackground.html",
- function( color, support, assert ) {
+ function( assert, jQuery, window, document, color, support ) {
assert.expect( 2 );
var okValue = {
"#000000": true,
@@ -29,21 +29,23 @@ if ( jQuery.css ) {
};
assert.ok( okValue[ color ], "color was not reset (" + color + ")" );
- assert.deepEqual( jQuery.extend( {}, support ), computedSupport, "Same support properties" );
+ assert.deepEqual( jQuery.extend( {}, support ), computedSupport,
+ "Same support properties" );
}
);
}
// This test checks CSP only for browsers with "Content-Security-Policy" header support
// i.e. no old WebKit or old Firefox
-testIframeWithCallback(
+testIframe(
"Check CSP (https://developer.mozilla.org/en-US/docs/Security/CSP) restrictions",
"support/csp.php",
- function( support, assert ) {
+ function( assert, jQuery, window, document, support ) {
var done = assert.async();
assert.expect( 2 );
- assert.deepEqual( jQuery.extend( {}, support ), computedSupport, "No violations of CSP polices" );
+ assert.deepEqual( jQuery.extend( {}, support ), computedSupport,
+ "No violations of CSP polices" );
supportjQuery.get( "data/support/csp.log" ).done( function( data ) {
assert.equal( data, "", "No log request should be sent" );
@@ -53,16 +55,17 @@ testIframeWithCallback(
);
( function() {
- var expected,
+ var expected, version,
userAgent = window.navigator.userAgent;
if ( /edge\//i.test( userAgent ) ) {
+ version = userAgent.match( /edge\/(\d+)/i )[ 1 ];
expected = {
"ajax": true,
"boxSizingReliable": true,
"checkClone": true,
"checkOn": true,
- "clearCloneStyle": false,
+ "clearCloneStyle": version >= 13,
"cors": true,
"createHTMLDocument": true,
"focusin": false,
@@ -127,7 +130,7 @@ testIframeWithCallback(
"radioValue": true,
"reliableMarginLeft": true
};
- } else if ( /9\.0(\.\d+|) safari/i.test( userAgent ) ) {
+ } else if ( /\b(?:9|10)\.\d(\.\d+)* safari/i.test( userAgent ) ) {
expected = {
"ajax": true,
"boxSizingReliable": true,
@@ -144,23 +147,6 @@ testIframeWithCallback(
"radioValue": true,
"reliableMarginLeft": true
};
- } else if ( /8\.0(\.\d+|) safari/i.test( userAgent ) ) {
- expected = {
- "ajax": true,
- "boxSizingReliable": true,
- "checkClone": true,
- "checkOn": true,
- "clearCloneStyle": true,
- "cors": true,
- "createHTMLDocument": false,
- "focusin": false,
- "noCloneChecked": true,
- "optSelected": true,
- "pixelMarginRight": true,
- "pixelPosition": false,
- "radioValue": true,
- "reliableMarginLeft": true
- };
} else if ( /firefox/i.test( userAgent ) ) {
expected = {
"ajax": true,
@@ -178,7 +164,7 @@ testIframeWithCallback(
"radioValue": true,
"reliableMarginLeft": false
};
- } else if ( /iphone os 9_/i.test( userAgent ) ) {
+ } else if ( /iphone os (?:9|10)_/i.test( userAgent ) ) {
expected = {
"ajax": true,
"boxSizingReliable": true,
@@ -272,6 +258,6 @@ testIframeWithCallback(
assert.ok( true, "no ajax; skipping jQuery.support['" + i + "']" );
}
}
- });
+ } );
} )();
diff --git a/test/unit/traversing.js b/test/unit/traversing.js
index 3e0c376..c7ed014 100644
--- a/test/unit/traversing.js
+++ b/test/unit/traversing.js
@@ -393,8 +393,31 @@ QUnit.test( "closest(jQuery)", function( assert ) {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "not(Selector)", function( assert ) {
assert.expect( 7 );
assert.equal( jQuery( "#qunit-fixture > p#ap > a" ).not( "#google" ).length, 2, "not('selector')" );
- assert.deepEqual( jQuery( "p" ).not( ".result" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "not('.class')" );
- assert.deepEqual( jQuery( "p" ).not( "#ap, #sndp, .result" ).get(), q( "firstp", "en", "sap", "first" ), "not('selector, selector')" );
+
+ assert.deepEqual(
+ jQuery( "#qunit-fixture p" ).not( ".result" ).get(),
+ q(
+ "firstp",
+ "ap",
+ "sndp",
+ "en",
+ "sap",
+ "first"
+ ),
+ "not('.class')"
+ );
+
+
+ assert.deepEqual(
+ jQuery( "#qunit-fixture p" ).not( "#ap, #sndp, .result" ).get(),
+ q(
+ "firstp",
+ "en",
+ "sap",
+ "first"
+ ),
+ "not('selector, selector')"
+ );
assert.deepEqual( jQuery( "#ap *" ).not( "code" ).get(), q( "google", "groups", "anchor1", "mark" ), "not('tag selector')" );
assert.deepEqual( jQuery( "#ap *" ).not( "code, #mark" ).get(), q( "google", "groups", "anchor1" ), "not('tag, ID selector')" );
@@ -440,7 +463,11 @@ QUnit.test( "not(Array)", function( assert ) {
QUnit.test( "not(jQuery)", function( assert ) {
assert.expect( 1 );
- assert.deepEqual( jQuery( "p" ).not( jQuery( "#ap, #sndp, .result" ) ).get(), q( "firstp", "en", "sap", "first" ), "not(jQuery)" );
+ assert.deepEqual(
+ jQuery( "#qunit-fixture p" ).not( jQuery( "#ap, #sndp, .result" ) ).get(),
+ q( "firstp", "en", "sap", "first" ),
+ "not(jQuery)"
+ );
} );
QUnit.test( "not(Selector) excludes non-element nodes (gh-2808)", function( assert ) {
@@ -454,6 +481,20 @@ QUnit.test( "not(Selector) excludes non-element nodes (gh-2808)", function( asse
assert.deepEqual( mixedContents.not( "[id=a],*,[id=b]" ).get(), [], "not [id=a],*,[id=b]" );
} );
+QUnit.test( "not(arraylike) passes non-element nodes (gh-3226)", function( assert ) {
+ assert.expect( 5 );
+
+ var mixedContents = jQuery( "<span id='nonnodesElement'>hi</span> there <!-- mon ami -->" ),
+ mixedLength = mixedContents.length,
+ firstElement = mixedContents.first();
+
+ assert.deepEqual( mixedContents.not( mixedContents ).get(), [], "not everything" );
+ assert.deepEqual( mixedContents.not( firstElement ).length, mixedLength - 1, "not firstElement" );
+ assert.deepEqual( mixedContents.not( [ firstElement[ 0 ].nextSibling ] ).length, mixedLength - 1, "not textnode array" );
+ assert.deepEqual( mixedContents.not( firstElement[ 0 ].nextSibling ).length, mixedLength - 1, "not textnode" );
+ assert.deepEqual( mixedContents.not( document.body ).get(), mixedContents.get(), "not with unmatched element" );
+} );
+
QUnit.test( "has(Element)", function( assert ) {
assert.expect( 3 );
var obj, detached, multipleParent;
diff --git a/test/unit/tween.js b/test/unit/tween.js
index f66aa37..28fcfad 100644
--- a/test/unit/tween.js
+++ b/test/unit/tween.js
@@ -160,7 +160,8 @@ QUnit.test( "jQuery.Tween - Plain Object", function( assert ) {
assert.equal( tween.now, 90, "Calculated tween" );
- assert.ok( easingSpy.calledWith( 0.1 ), "...using jQuery.easing.linear" );
+ assert.ok( easingSpy.calledWith( 0.1, 0.1 * testOptions.duration, 0, 1, testOptions.duration ),
+ "...using jQuery.easing.linear with back-compat arguments" );
assert.equal( testObject.test, 90, "Set value" );
tween.run( 1 );
@@ -199,7 +200,10 @@ QUnit.test( "jQuery.Tween - Element", function( assert ) {
eased = 100 - ( jQuery.easing.swing( 0.1 ) * 100 );
assert.equal( tween.now, eased, "Calculated tween" );
- assert.ok( easingSpy.calledWith( 0.1 ), "...using jQuery.easing.linear" );
+ assert.ok(
+ easingSpy.calledWith( 0.1, 0.1 * testOptions.duration, 0, 1, testOptions.duration ),
+ "...using jQuery.easing.linear with back-compat arguments"
+ );
assert.equal(
parseFloat( testElement.style.height ).toFixed( 2 ),
eased.toFixed( 2 ), "Set value"
diff --git a/test/unit/wrap.js b/test/unit/wrap.js
index 80abd9e..65af2b4 100644
--- a/test/unit/wrap.js
+++ b/test/unit/wrap.js
@@ -60,7 +60,7 @@ function testWrap( val, assert ) {
j.wrap( val( "<i></i>" ) );
assert.equal(
- jQuery( "#nonnodes > i" ).length, jQuery( "#nonnodes" )[ 0 ].childNodes.length,
+ jQuery( "#nonnodes > i" ).length, 3,
"Check node,textnode,comment wraps ok"
);
assert.equal(
@@ -472,7 +472,7 @@ QUnit.test( "unwrap( selector )", function( assert ) {
jQuery( "#unwrap1" ).length, 1, "still wrapped"
);
- // Shouldn't unwrap, no match
+ // Shouldn't unwrap, no match
jQuery( "#unwrap1 span" ) .unwrap( "span" );
assert.equal(
jQuery( "#unwrap1" ).length, 1, "still wrapped"
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/jquery.git
More information about the Pkg-javascript-commits
mailing list