mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Build: migrate most grunt tasks off of grunt (3.x)
Close gh-5330 - lint - npmcopy - build, minify, and process for distribution. - new custom build command using yargs - compare size of minified/gzip built files - pretest scripts, including qunit-fixture, babel transpilation, and npmcopy - node smoke tests - promises aplus tests - new watch task using nodemon, which runs `npm run build:all` on `src` changes. Also: - upgraded husky and added the new lint command - updated lint config to use new "flat" config format. See https://eslint.org/docs/latest/use/configure/configuration-files-new - Temporarily disabled one lint rule until flat config is supported by eslint-plugin-import. See https://github.com/import-js/eslint-plugin-import/issues/2556 - committed package-lock.json - updated all test scripts to use the new build - added an express test server that uses middleware-mockserver this can be used to run tests without karma - build-all-variants is now build:all - run pretest script in jenkins --------- Co-authored-by: Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
This commit is contained in:
parent
6fe88690a3
commit
ec8802bafe
@ -10,7 +10,7 @@ charset = utf-8
|
|||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[package.json]
|
[*.{json,yml}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
external
|
|
||||||
node_modules
|
|
||||||
*.min.js
|
|
||||||
dist/**
|
|
||||||
!dist/jquery.js
|
|
||||||
!dist/jquery.min.js
|
|
||||||
!dist/jquery.slim.js
|
|
||||||
!dist/jquery.slim.min.js
|
|
||||||
test/data/jquery-1.9.1.js
|
|
||||||
test/data/badcall.js
|
|
||||||
test/data/badjson.js
|
|
||||||
test/data/json_obj.js
|
|
||||||
test/data/readywaitasset.js
|
|
||||||
test/data/readywaitloader.js
|
|
||||||
test/data/support/csp.js
|
|
||||||
test/data/support/getComputedSupport.js
|
|
||||||
test/data/core/jquery-iterability-transpiled.js
|
|
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "jquery",
|
|
||||||
|
|
||||||
"reportUnusedDisableDirectives": 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
|
|
||||||
},
|
|
||||||
|
|
||||||
// The browser env is not enabled on purpose so that code takes
|
|
||||||
// all browser-only globals from window instead of assuming
|
|
||||||
// they're available as globals. This makes it possible to use
|
|
||||||
// jQuery with tools like jsdom which provide a custom window
|
|
||||||
// implementation.
|
|
||||||
"env": {},
|
|
||||||
|
|
||||||
"globals": {
|
|
||||||
"window": true,
|
|
||||||
"define": true,
|
|
||||||
"module": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
"one-var": ["error", {"var": "always"}],
|
|
||||||
"strict": ["error", "function"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "jquery",
|
|
||||||
|
|
||||||
"reportUnusedDisableDirectives": true,
|
|
||||||
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2017
|
|
||||||
},
|
|
||||||
|
|
||||||
"env": {
|
|
||||||
"es6": true,
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
"strict": ["error", "global"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "./.eslintrc-node.json"
|
|
||||||
}
|
|
15
.github/workflows/node.js.yml
vendored
15
.github/workflows/node.js.yml
vendored
@ -40,6 +40,7 @@ jobs:
|
|||||||
NODE_VERSION: "18.x"
|
NODE_VERSION: "18.x"
|
||||||
NPM_SCRIPT: "test:browser"
|
NPM_SCRIPT: "test:browser"
|
||||||
BROWSERS: "FirefoxHeadless"
|
BROWSERS: "FirefoxHeadless"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||||
@ -61,15 +62,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
export FIREFOX_SOURCE_URL='https://download.mozilla.org/?product=firefox-esr-latest&lang=en-US&os=linux64'
|
export FIREFOX_SOURCE_URL='https://download.mozilla.org/?product=firefox-esr-latest&lang=en-US&os=linux64'
|
||||||
wget --no-verbose $FIREFOX_SOURCE_URL -O - | tar -jx -C ${HOME}
|
wget --no-verbose $FIREFOX_SOURCE_URL -O - | tar -jx -C ${HOME}
|
||||||
if: "contains(matrix.NAME, 'Firefox ESR')"
|
if: contains(matrix.NAME, 'Firefox ESR')
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: npm install
|
||||||
npm install
|
|
||||||
|
|
||||||
- name: Install Playwright dependencies
|
- name: Install Playwright dependencies
|
||||||
run: npx playwright-webkit install-deps
|
run: npx playwright-webkit install-deps
|
||||||
if: "matrix.NPM_SCRIPT == 'test:browser' && contains(matrix.BROWSERS, 'WebkitHeadless')"
|
if: matrix.NPM_SCRIPT == 'test:browser' && contains(matrix.BROWSERS, 'WebkitHeadless')
|
||||||
|
|
||||||
|
- name: Lint code
|
||||||
|
run: npm run build && npm run lint
|
||||||
|
if: matrix.NODE_VERSION == '18.x'
|
||||||
|
|
||||||
|
- name: Prepare tests
|
||||||
|
run: npm run pretest
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
env:
|
env:
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -8,14 +8,13 @@
|
|||||||
.bower.json
|
.bower.json
|
||||||
.sizecache.json
|
.sizecache.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
.eslintcache
|
||||||
|
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|
||||||
# Ignore everything in `dist` folder except for the ESLint config
|
/dist
|
||||||
/dist/*
|
|
||||||
!/dist/.eslintrc.json
|
|
||||||
|
|
||||||
|
/external
|
||||||
/node_modules
|
/node_modules
|
||||||
|
|
||||||
/test/data/core/jquery-iterability-transpiled.js
|
/test/data/core/jquery-iterability-transpiled.js
|
||||||
|
4
.husky/commit-msg
Executable file
4
.husky/commit-msg
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npx commitplease .git/COMMIT_EDITMSG
|
5
.husky/pre-commit
Executable file
5
.husky/pre-commit
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npm run lint
|
||||||
|
npm run qunit-fixture
|
@ -1,5 +1,5 @@
|
|||||||
.eslintignore
|
.eslintignore
|
||||||
.eslintrc.json
|
eslint.config.js
|
||||||
|
|
||||||
/.editorconfig
|
/.editorconfig
|
||||||
/.gitattributes
|
/.gitattributes
|
||||||
|
@ -124,10 +124,10 @@ This will only run the "css" module tests. This will significantly speed up your
|
|||||||
|
|
||||||
#### Loading changes on the test page
|
#### Loading changes on the test page
|
||||||
|
|
||||||
Rather than rebuilding jQuery with `grunt` every time you make a change, you can use the included `grunt watch` task to rebuild distribution files whenever a file is saved.
|
Rather than rebuilding jQuery with `npm run build` every time you make a change, you can use the included watch task to rebuild distribution files whenever a file is saved.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ grunt watch
|
$ npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can **load tests in AMD** to avoid the need for rebuilding altogether.
|
Alternatively, you can **load tests in AMD** to avoid the need for rebuilding altogether.
|
||||||
|
238
Gruntfile.js
238
Gruntfile.js
@ -1,20 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = function( grunt ) {
|
module.exports = function( grunt ) {
|
||||||
function readOptionalJSON( filepath ) {
|
|
||||||
const stripJSONComments = require( "strip-json-comments" );
|
|
||||||
let data = {};
|
|
||||||
try {
|
|
||||||
data = JSON.parse( stripJSONComments(
|
|
||||||
fs.readFileSync( filepath, { encoding: "utf8" } )
|
|
||||||
) );
|
|
||||||
} catch ( e ) {}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fs = require( "fs" );
|
|
||||||
const { spawn } = require( "child_process" );
|
|
||||||
const gzip = require( "gzip-js" );
|
|
||||||
const nodeV16OrNewer = !/^v1[0-5]\./.test( process.version );
|
const nodeV16OrNewer = !/^v1[0-5]\./.test( process.version );
|
||||||
const nodeV17OrNewer = !/^v1[0-6]\./.test( process.version );
|
const nodeV17OrNewer = !/^v1[0-6]\./.test( process.version );
|
||||||
const customBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
|
const customBrowsers = process.env.BROWSERS && process.env.BROWSERS.split( "," );
|
||||||
@ -34,112 +20,8 @@ module.exports = function( grunt ) {
|
|||||||
grunt.option( "filename", "jquery.js" );
|
grunt.option( "filename", "jquery.js" );
|
||||||
}
|
}
|
||||||
|
|
||||||
const builtJsFiles = [
|
|
||||||
"dist/jquery.js",
|
|
||||||
"dist/jquery.min.js",
|
|
||||||
"dist/jquery.slim.js",
|
|
||||||
"dist/jquery.slim.min.js"
|
|
||||||
];
|
|
||||||
|
|
||||||
const builtJsMinFiles = builtJsFiles
|
|
||||||
.filter( filepath => filepath.endsWith( ".min.js" ) );
|
|
||||||
|
|
||||||
grunt.initConfig( {
|
grunt.initConfig( {
|
||||||
pkg: grunt.file.readJSON( "package.json" ),
|
pkg: grunt.file.readJSON( "package.json" ),
|
||||||
dst: readOptionalJSON( "dist/.destination.json" ),
|
|
||||||
compare_size: {
|
|
||||||
files: builtJsMinFiles,
|
|
||||||
options: {
|
|
||||||
compress: {
|
|
||||||
gz: function( contents ) {
|
|
||||||
return gzip.zip( contents, {} ).length;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cache: "build/.sizecache.json"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
babel: {
|
|
||||||
options: {
|
|
||||||
sourceMap: "inline",
|
|
||||||
retainLines: true,
|
|
||||||
plugins: [ "@babel/transform-for-of" ]
|
|
||||||
},
|
|
||||||
tests: {
|
|
||||||
files: {
|
|
||||||
"test/data/core/jquery-iterability-transpiled.js":
|
|
||||||
"test/data/core/jquery-iterability-transpiled-es6.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
all: {
|
|
||||||
dest: "dist/jquery.js",
|
|
||||||
minimum: [
|
|
||||||
"core"
|
|
||||||
],
|
|
||||||
|
|
||||||
// Exclude specified modules if the module matching the key is removed
|
|
||||||
removeWith: {
|
|
||||||
ajax: [ "manipulation/_evalUrl", "deprecated/ajax-event-alias" ],
|
|
||||||
callbacks: [ "deferred" ],
|
|
||||||
css: [ "effects", "dimensions", "offset" ],
|
|
||||||
"css/showHide": [ "effects" ],
|
|
||||||
deferred: {
|
|
||||||
remove: [ "ajax", "effects", "queue", "core/ready" ],
|
|
||||||
include: [ "core/ready-no-deferred" ]
|
|
||||||
},
|
|
||||||
event: [ "deprecated/ajax-event-alias", "deprecated/event" ],
|
|
||||||
selector: [ "css/hiddenVisibleSelectors", "effects/animatedSelector" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
npmcopy: {
|
|
||||||
all: {
|
|
||||||
options: {
|
|
||||||
destPrefix: "external"
|
|
||||||
},
|
|
||||||
files: {
|
|
||||||
"bootstrap/bootstrap.css": "bootstrap/dist/css/bootstrap.css",
|
|
||||||
"bootstrap/bootstrap.min.css": "bootstrap/dist/css/bootstrap.min.css",
|
|
||||||
"bootstrap/bootstrap.min.css.map": "bootstrap/dist/css/bootstrap.min.css.map",
|
|
||||||
|
|
||||||
"core-js/core-js.js": "core-js/client/core.min.js",
|
|
||||||
"core-js/LICENSE.txt": "core-js/LICENSE",
|
|
||||||
|
|
||||||
"npo/npo.js": "native-promise-only/lib/npo.src.js",
|
|
||||||
|
|
||||||
"qunit/qunit.js": "qunit/qunit/qunit.js",
|
|
||||||
"qunit/qunit.css": "qunit/qunit/qunit.css",
|
|
||||||
"qunit/LICENSE.txt": "qunit/LICENSE.txt",
|
|
||||||
|
|
||||||
"requirejs/require.js": "requirejs/require.js",
|
|
||||||
|
|
||||||
"sinon/sinon.js": "sinon/pkg/sinon.js",
|
|
||||||
"sinon/LICENSE.txt": "sinon/LICENSE"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
jsonlint: {
|
|
||||||
pkg: {
|
|
||||||
src: [ "package.json" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
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: builtJsFiles
|
|
||||||
},
|
|
||||||
dev: {
|
|
||||||
src: [ "src/**/*.js", "Gruntfile.js", "test/**/*.js", "build/**/*.js" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
testswarm: {
|
testswarm: {
|
||||||
tests: [
|
tests: [
|
||||||
|
|
||||||
@ -206,9 +88,14 @@ module.exports = function( grunt ) {
|
|||||||
"external/npo/npo.js",
|
"external/npo/npo.js",
|
||||||
"external/requirejs/require.js",
|
"external/requirejs/require.js",
|
||||||
"test/data/testinit.js",
|
"test/data/testinit.js",
|
||||||
|
|
||||||
"test/jquery.js",
|
"test/jquery.js",
|
||||||
|
|
||||||
|
{
|
||||||
|
pattern: "external/**",
|
||||||
|
included: false,
|
||||||
|
served: true,
|
||||||
|
nocache: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
pattern: "dist/jquery.*",
|
pattern: "dist/jquery.*",
|
||||||
included: false,
|
included: false,
|
||||||
@ -221,13 +108,6 @@ module.exports = function( grunt ) {
|
|||||||
served: true,
|
served: true,
|
||||||
nocache: true
|
nocache: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
pattern: "external/**",
|
|
||||||
included: false,
|
|
||||||
served: true,
|
|
||||||
nocache: true
|
|
||||||
},
|
|
||||||
{ pattern: "node_modules/**", included: false, served: true },
|
|
||||||
{
|
{
|
||||||
pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
|
pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
|
||||||
included: false,
|
included: false,
|
||||||
@ -281,7 +161,6 @@ module.exports = function( grunt ) {
|
|||||||
// jsdom only runs basic tests
|
// jsdom only runs basic tests
|
||||||
"test/unit/basic.js",
|
"test/unit/basic.js",
|
||||||
|
|
||||||
{ pattern: "external/**", included: false, served: true },
|
|
||||||
{
|
{
|
||||||
pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
|
pattern: "test/**/*.@(js|css|jpg|html|xml|svg)",
|
||||||
included: false,
|
included: false,
|
||||||
@ -310,100 +189,27 @@ module.exports = function( grunt ) {
|
|||||||
browsers: [ "IE" ],
|
browsers: [ "IE" ],
|
||||||
singleRun: false
|
singleRun: false
|
||||||
}
|
}
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
files: [ "<%= eslint.dev.src %>" ],
|
|
||||||
tasks: [ "dev" ]
|
|
||||||
},
|
|
||||||
uglify: {
|
|
||||||
all: {
|
|
||||||
files: {
|
|
||||||
"dist/<%= grunt.option('filename').replace(/\\.js$/, '.min.js') %>":
|
|
||||||
"dist/<%= grunt.option('filename') %>"
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
preserveComments: false,
|
|
||||||
sourceMap: true,
|
|
||||||
sourceMapName:
|
|
||||||
"dist/<%= grunt.option('filename').replace('.js', '.min.map') %>",
|
|
||||||
report: "min",
|
|
||||||
output: {
|
|
||||||
"ascii_only": true,
|
|
||||||
|
|
||||||
// Support: Android 4.0 only
|
|
||||||
// UglifyJS 3 breaks Android 4.0 if this option is not enabled.
|
|
||||||
// This is in lieu of setting ie8 for all of mangle, compress, and output
|
|
||||||
"ie8": true
|
|
||||||
},
|
|
||||||
banner: "/*! jQuery v<%= pkg.version %> | " +
|
|
||||||
"(c) OpenJS Foundation and other contributors | jquery.org/license */",
|
|
||||||
compress: {
|
|
||||||
"hoist_funs": false,
|
|
||||||
loops: false,
|
|
||||||
|
|
||||||
// Support: IE <11
|
|
||||||
// typeofs transformation is unsafe for IE9-10
|
|
||||||
// See https://github.com/mishoo/UglifyJS2/issues/2198
|
|
||||||
typeofs: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Load grunt tasks from NPM packages
|
// Load grunt tasks from NPM packages
|
||||||
require( "load-grunt-tasks" )( grunt, {
|
require( "load-grunt-tasks" )( grunt, {
|
||||||
pattern: nodeV16OrNewer ? [ "grunt-*" ] : [ "grunt-*", "!grunt-eslint" ]
|
pattern: [ "grunt-*" ]
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Integrate jQuery specific tasks
|
// Integrate jQuery specific tasks
|
||||||
grunt.loadTasks( "build/tasks" );
|
grunt.loadTasks( "build/grunt-tasks" );
|
||||||
|
|
||||||
grunt.registerTask( "print_old_node_message", ( ...args ) => {
|
grunt.registerTask( "print_old_node_message", ( ...args ) => {
|
||||||
var task = args.join( ":" );
|
var task = args.join( ":" );
|
||||||
grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." );
|
grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
grunt.registerTask( "build-all-variants",
|
|
||||||
"Build both the full & slim builds",
|
|
||||||
function() {
|
|
||||||
const done = this.async();
|
|
||||||
|
|
||||||
spawn( "npm run build-all-variants", {
|
|
||||||
stdio: "inherit",
|
|
||||||
shell: true
|
|
||||||
} )
|
|
||||||
.on( "close", code => {
|
|
||||||
done( code === 0 );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
grunt.registerTask( "print_jsdom_message", () => {
|
grunt.registerTask( "print_jsdom_message", () => {
|
||||||
grunt.log.writeln( "Node.js 17 or newer detected, skipping jsdom tests..." );
|
grunt.log.writeln( "Node.js 17 or newer detected, skipping jsdom tests..." );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
grunt.registerTask( "lint", [
|
grunt.registerTask( "test:jsdom", [
|
||||||
"jsonlint",
|
|
||||||
|
|
||||||
// Running the full eslint task without breaking it down to targets
|
|
||||||
// would run the dist target first which would point to errors in the built
|
|
||||||
// file, making it harder to fix them. We want to check the built file only
|
|
||||||
// if we already know the source files pass the linter.
|
|
||||||
runIfNewNode( "eslint:dev" ),
|
|
||||||
runIfNewNode( "eslint:dist" )
|
|
||||||
] );
|
|
||||||
|
|
||||||
grunt.registerTask( "lint:newer", [
|
|
||||||
"newer:jsonlint",
|
|
||||||
|
|
||||||
// Don't replace it with just the task; see the above comment.
|
|
||||||
runIfNewNode( "newer:eslint:dev" ),
|
|
||||||
runIfNewNode( "newer:eslint:dist" )
|
|
||||||
] );
|
|
||||||
|
|
||||||
grunt.registerTask( "test:fast", [ "node_smoke_tests" ] );
|
|
||||||
grunt.registerTask( "test:slow", [
|
|
||||||
runIfNewNode( "promises_aplus_tests" ),
|
|
||||||
|
|
||||||
// Support: Node.js 17+
|
// Support: Node.js 17+
|
||||||
// jsdom fails to connect to the Karma server in Node 17+.
|
// jsdom fails to connect to the Karma server in Node 17+.
|
||||||
@ -411,33 +217,11 @@ module.exports = function( grunt ) {
|
|||||||
nodeV17OrNewer ? "print_jsdom_message" : runIfNewNode( "karma:jsdom" )
|
nodeV17OrNewer ? "print_jsdom_message" : runIfNewNode( "karma:jsdom" )
|
||||||
] );
|
] );
|
||||||
|
|
||||||
grunt.registerTask( "test:prepare", [
|
|
||||||
"qunit_fixture",
|
|
||||||
"babel:tests"
|
|
||||||
] );
|
|
||||||
|
|
||||||
grunt.registerTask( "test", [
|
grunt.registerTask( "test", [
|
||||||
"test:prepare",
|
"test:jsdom"
|
||||||
"test:fast",
|
|
||||||
"test:slow"
|
|
||||||
] );
|
|
||||||
|
|
||||||
grunt.registerTask( "dev", [
|
|
||||||
"build:*:*",
|
|
||||||
runIfNewNode( "newer:eslint:dev" ),
|
|
||||||
"newer:uglify",
|
|
||||||
"remove_map_comment",
|
|
||||||
"dist:*",
|
|
||||||
"qunit_fixture",
|
|
||||||
"compare_size"
|
|
||||||
] );
|
] );
|
||||||
|
|
||||||
grunt.registerTask( "default", [
|
grunt.registerTask( "default", [
|
||||||
runIfNewNode( "eslint:dev" ),
|
"test"
|
||||||
"build-all-variants",
|
|
||||||
"test:prepare",
|
|
||||||
runIfNewNode( "eslint:dist" ),
|
|
||||||
"test:fast",
|
|
||||||
"compare_size"
|
|
||||||
] );
|
] );
|
||||||
};
|
};
|
||||||
|
146
README.md
146
README.md
@ -35,7 +35,7 @@ To build jQuery, you need to have the latest Node.js/npm and git 1.7 or later. E
|
|||||||
|
|
||||||
For Windows, you have to download and install [git](https://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](https://brew.sh/). Once Homebrew is installed, run `brew install git` to install git,
|
macOS users should install [Homebrew](https://brew.sh/). Once Homebrew is installed, run `brew install git` to install git,
|
||||||
and `brew install node` to install Node.js.
|
and `brew install node` to install Node.js.
|
||||||
|
|
||||||
Linux/BSD users should use their appropriate package managers to install git and Node.js, or build from source
|
Linux/BSD users should use their appropriate package managers to install git and Node.js, or build from source
|
||||||
@ -45,47 +45,47 @@ if you swing that way. Easy-peasy.
|
|||||||
How to build your own jQuery
|
How to build your own jQuery
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
Clone a copy of the main jQuery git repo by running:
|
First, [clone the jQuery git repo](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository).
|
||||||
|
|
||||||
|
Then, enter the jquery directory, install dependencies, and run the build script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git://github.com/jquery/jquery.git
|
cd jquery
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter the jquery directory and run the build script:
|
The built version of jQuery will be placed in the `dist/` directory, along with a minified copy and associated map file.
|
||||||
|
|
||||||
|
## Build all jQuery release files
|
||||||
|
|
||||||
|
To build all variants of jQuery, run the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd jquery && npm run build
|
npm run build:all
|
||||||
```
|
|
||||||
The built version of jQuery will be put in the `dist/` subdirectory, along with the minified copy and associated map file.
|
|
||||||
|
|
||||||
If you want to create custom build or help with jQuery development, it would be better to install [grunt command line interface](https://github.com/gruntjs/grunt-cli) as a global package:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install -g grunt-cli
|
|
||||||
```
|
|
||||||
Make sure you have `grunt` installed by testing:
|
|
||||||
```
|
|
||||||
grunt -V
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now by running the `grunt` command, in the jquery directory, you can build a full version of jQuery, just like with an `npm run build` command:
|
This will create all of the variants that jQuery includes in a release, including `jquery.js` and `jquery.slim.js` along their associated minified files and sourcemaps.
|
||||||
```
|
|
||||||
grunt
|
|
||||||
```
|
|
||||||
|
|
||||||
There are many other tasks available for jQuery Core:
|
## Building a Custom jQuery
|
||||||
```
|
|
||||||
grunt -help
|
The build script can be used to create a custom version of jQuery that includes only the modules you need.
|
||||||
|
|
||||||
|
Any module may be excluded except for `core`. When excluding `selector`, it is not removed but replaced with a small wrapper around native `querySelectorAll` (see below for more information).
|
||||||
|
|
||||||
|
### Build Script Help
|
||||||
|
|
||||||
|
To see the full list of available options for the build script, run the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Modules
|
### Modules
|
||||||
|
|
||||||
Special builds can be created that exclude subsets of jQuery functionality.
|
To exclude a module, pass its path relative to the `src` folder (without the `.js` extension) to the `--exclude` option. When using the `--include` option, the default includes are dropped and a build is created with only those modules.
|
||||||
This allows for smaller custom builds when the builder is certain that those parts of jQuery are not being used.
|
|
||||||
For example, an app that only used JSONP for `$.ajax()` and did not need to calculate offsets or positions of elements could exclude the offset and ajax/xhr modules.
|
|
||||||
|
|
||||||
Any module may be excluded except for `core`, and `selector`. To exclude a module, pass its path relative to the `src` folder (without the `.js` extension).
|
Some example modules that can be excluded or included are:
|
||||||
|
|
||||||
Some example modules that can be excluded are:
|
|
||||||
|
|
||||||
- **ajax**: All AJAX functionality: `$.ajax()`, `$.get()`, `$.post()`, `$.ajaxSetup()`, `.load()`, transports, and ajax event shorthands such as `.ajaxStart()`.
|
- **ajax**: All AJAX functionality: `$.ajax()`, `$.get()`, `$.post()`, `$.ajaxSetup()`, `.load()`, transports, and ajax event shorthands such as `.ajaxStart()`.
|
||||||
- **ajax/xhr**: The XMLHTTPRequest AJAX transport only.
|
- **ajax/xhr**: The XMLHTTPRequest AJAX transport only.
|
||||||
@ -101,84 +101,67 @@ Some example modules that can be excluded are:
|
|||||||
- **offset**: The `.offset()`, `.position()`, `.offsetParent()`, `.scrollLeft()`, and `.scrollTop()` methods.
|
- **offset**: The `.offset()`, `.position()`, `.offsetParent()`, `.scrollLeft()`, and `.scrollTop()` methods.
|
||||||
- **wrap**: The `.wrap()`, `.wrapAll()`, `.wrapInner()`, and `.unwrap()` methods.
|
- **wrap**: The `.wrap()`, `.wrapAll()`, `.wrapInner()`, and `.unwrap()` methods.
|
||||||
- **core/ready**: Exclude the ready module if you place your scripts at the end of the body. Any ready callbacks bound with `jQuery()` will simply be called immediately. However, `jQuery(document).ready()` will not be a function and `.on("ready", ...)` or similar will not be triggered.
|
- **core/ready**: Exclude the ready module if you place your scripts at the end of the body. Any ready callbacks bound with `jQuery()` will simply be called immediately. However, `jQuery(document).ready()` will not be a function and `.on("ready", ...)` or similar will not be triggered.
|
||||||
- **deferred**: Exclude jQuery.Deferred. This also removes jQuery.Callbacks. *Note* that modules that depend on jQuery.Deferred(AJAX, effects, core/ready) will not be removed and will still expect jQuery.Deferred to be there. Include your own jQuery.Deferred implementation or exclude those modules as well (`grunt custom:-deferred,-ajax,-effects,-core/ready`).
|
- **deferred**: Exclude jQuery.Deferred. This also excludes all modules that rely on Deferred, including **ajax**, **effects**, and **queue**, but replaces **core/ready** with **core/ready-no-deferred**.
|
||||||
- **exports/global**: Exclude the attachment of global jQuery variables ($ and jQuery) to the window.
|
- **exports/global**: Exclude the attachment of global jQuery variables ($ and jQuery) to the window.
|
||||||
- **exports/amd**: Exclude the AMD definition.
|
- **exports/amd**: Exclude the AMD definition.
|
||||||
|
|
||||||
As a special case, you may also replace the full jQuery `selector` module by using a special flag `grunt custom:-selector`.
|
- **selector**: The full jQuery selector engine. When this module is excluded, it is replaced with a rudimentary selector engine based on the browser's `querySelectorAll` method that does not support jQuery selector extensions or enhanced semantics. See the [selector-native.js](https://github.com/jquery/jquery/blob/main/src/selector-native.js) file for details.
|
||||||
|
|
||||||
- **selector**: The full jQuery selector engine. When this module is excluded, it is replaced by a rudimentary selector engine based on the browser's `querySelectorAll` method that does not support jQuery selector extensions or enhanced semantics. See the [selector-native.js](https://github.com/jquery/jquery/blob/main/src/selector-native.js) file for details.
|
|
||||||
|
|
||||||
For backwards compatibility purposes, the name `sizzle` is recognized as the alias for `selector`.
|
|
||||||
|
|
||||||
*Note*: Excluding the full `selector` module will also exclude all jQuery selector extensions (such as `effects/animatedSelector` and `css/hiddenVisibleSelectors`).
|
*Note*: Excluding the full `selector` module will also exclude all jQuery selector extensions (such as `effects/animatedSelector` and `css/hiddenVisibleSelectors`).
|
||||||
|
|
||||||
The build process shows a message for each dependent module it excludes or includes.
|
|
||||||
|
|
||||||
##### AMD name
|
##### AMD name
|
||||||
|
|
||||||
As an option, you can set the module name for jQuery's AMD definition. By default, it is set to "jquery", which plays nicely with plugins and third-party libraries, but there may be cases where you'd like to change this. Simply pass it to the `--amd` parameter:
|
You can set the module name for jQuery's AMD definition. By default, it is set to "jquery", which plays nicely with plugins and third-party libraries, but there may be cases where you'd like to change this. Pass it to the `--amd` parameter:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom --amd="custom-name"
|
npm run build -- --amd="custom-name"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, to define anonymously, set the name to an empty string.
|
Or, to define anonymously, leave the name blank.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom --amd=""
|
npm run build -- --amd
|
||||||
```
|
```
|
||||||
|
|
||||||
##### File name
|
##### File name and directory
|
||||||
|
|
||||||
The default name for the built jQuery file is `jquery.js`; it is placed under the `dist/` directory. It's possible to change the file name using the `--filename` parameter:
|
The default name for the built jQuery file is `jquery.js`; it is placed under the `dist/` directory. It's possible to change the file name using `--filename` and the directory using `--dir`. `--dir` is relative to the project root.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom:slim --filename="jquery.slim.js"
|
npm run build -- --slim --filename="jquery.slim.js" --dir="/tmp"
|
||||||
```
|
```
|
||||||
|
|
||||||
This would create a slim version of jQuery and place it under `dist/jquery.slim.js`. In fact, this is exactly the command we use to generate the slim jQuery during the release process.
|
This would create a slim version of jQuery and place it under `tmp/jquery.slim.js`.
|
||||||
|
|
||||||
#### Custom Build Examples
|
#### Custom Build Examples
|
||||||
|
|
||||||
To create a custom build, first check out the version:
|
Create a custom build using `npm run build`, listing the modules to be excluded. Excluding a top-level module also excludes its corresponding directory of modules.
|
||||||
|
|
||||||
```bash
|
|
||||||
git pull; git checkout VERSION
|
|
||||||
```
|
|
||||||
|
|
||||||
Where VERSION is the version you want to customize. Then, make sure all Node dependencies are installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
Create the custom build using the `grunt custom` option, listing the modules to be excluded.
|
|
||||||
|
|
||||||
Exclude all **ajax** functionality:
|
Exclude all **ajax** functionality:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom:-ajax
|
npm run build -- --exclude=ajax
|
||||||
```
|
```
|
||||||
|
|
||||||
Excluding **css** removes modules depending on CSS: **effects**, **offset**, **dimensions**.
|
Excluding **css** removes modules depending on CSS: **effects**, **offset**, **dimensions**.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom:-css
|
npm run build -- --exclude=css
|
||||||
```
|
```
|
||||||
|
|
||||||
Exclude a bunch of modules:
|
Exclude a bunch of modules (`-e` is an alias for `--exclude`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom:-ajax/jsonp,-css,-deprecated,-dimensions,-effects,-offset,-wrap
|
npm run build -- -e ajax/jsonp -e css -e deprecated -e dimensions -e effects -e offset -e wrap
|
||||||
```
|
```
|
||||||
|
|
||||||
There is also a special alias to generate a build with the same configuration as the official jQuery Slim build is generated:
|
There is a special alias to generate a build with the same configuration as the official jQuery Slim build:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt custom:slim
|
npm run build -- --filename=jquery.slim.js --slim
|
||||||
```
|
```
|
||||||
|
|
||||||
For questions or requests regarding custom builds, please start a thread on the [Developing jQuery Core](https://forum.jquery.com/developing-jquery-core) section of the forum. Due to the combinatorics and custom nature of these builds, they are not regularly tested in jQuery's unit test process.
|
*Non-official custom builds are not regularly tested. Use them at your own risk.*
|
||||||
|
|
||||||
Running the Unit Tests
|
Running the Unit Tests
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
@ -189,10 +172,10 @@ Make sure you have the necessary dependencies:
|
|||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
Start `grunt watch` or `npm start` to auto-build jQuery as you work:
|
Start `npm start` to auto-build jQuery as you work:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grunt watch
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -205,35 +188,6 @@ Run the unit tests with a local server that supports PHP. Ensure that you run th
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Building to a different directory
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
To copy the built jQuery files from `/dist` to another directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
grunt && grunt dist:/path/to/special/location/
|
|
||||||
```
|
|
||||||
With this example, the output files would be:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
/path/to/special/location/jquery.js
|
|
||||||
/path/to/special/location/jquery.min.js
|
|
||||||
```
|
|
||||||
|
|
||||||
To add a permanent copy destination, create a file in `dist/` called ".destination.json". Inside the file, paste and customize the following:
|
|
||||||
|
|
||||||
```json
|
|
||||||
|
|
||||||
{
|
|
||||||
"/Absolute/path/to/other/destination": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Additionally, both methods can be combined.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Essential Git
|
Essential Git
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
69
build/command.js
Executable file
69
build/command.js
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { build } = require( "./tasks/build" );
|
||||||
|
const yargs = require( "yargs/yargs" );
|
||||||
|
const slimExclude = require( "./tasks/lib/slim-exclude" );
|
||||||
|
|
||||||
|
const argv = yargs( process.argv.slice( 2 ) )
|
||||||
|
.version( false )
|
||||||
|
.command( {
|
||||||
|
command: "[options]",
|
||||||
|
describe: "Build a jQuery bundle"
|
||||||
|
} )
|
||||||
|
.option( "filename", {
|
||||||
|
alias: "f",
|
||||||
|
type: "string",
|
||||||
|
description:
|
||||||
|
"Set the filename of the built file. Defaults to jquery.js."
|
||||||
|
} )
|
||||||
|
.option( "dir", {
|
||||||
|
alias: "d",
|
||||||
|
type: "string",
|
||||||
|
description:
|
||||||
|
"Set the dir to which to output the built file. Defaults to /dist."
|
||||||
|
} )
|
||||||
|
.option( "version", {
|
||||||
|
alias: "v",
|
||||||
|
type: "string",
|
||||||
|
description:
|
||||||
|
"Set the version to include in the built file. " +
|
||||||
|
"Defaults to the version in package.json plus the " +
|
||||||
|
"short commit SHA and any excluded modules."
|
||||||
|
} )
|
||||||
|
.option( "watch", {
|
||||||
|
alias: "w",
|
||||||
|
type: "boolean",
|
||||||
|
description:
|
||||||
|
"Watch the source files and rebuild when they change."
|
||||||
|
} )
|
||||||
|
.option( "exclude", {
|
||||||
|
alias: "e",
|
||||||
|
type: "array",
|
||||||
|
description:
|
||||||
|
"Modules to exclude from the build. " +
|
||||||
|
"Specifying this option will cause the " +
|
||||||
|
"specified modules to be excluded from the build."
|
||||||
|
} )
|
||||||
|
.option( "include", {
|
||||||
|
alias: "i",
|
||||||
|
type: "array",
|
||||||
|
description:
|
||||||
|
"Modules to include in the build. " +
|
||||||
|
"Specifying this option will override the " +
|
||||||
|
"default included modules and only include these modules."
|
||||||
|
} )
|
||||||
|
.option( "slim", {
|
||||||
|
alias: "s",
|
||||||
|
type: "boolean",
|
||||||
|
description: "Build a slim bundle, which excludes " +
|
||||||
|
slimExclude.join( ", " )
|
||||||
|
} )
|
||||||
|
.option( "amd", {
|
||||||
|
type: "string",
|
||||||
|
description:
|
||||||
|
"Set the name of the AMD module. Leave blank to make an anonymous module."
|
||||||
|
} )
|
||||||
|
.help()
|
||||||
|
.argv;
|
||||||
|
|
||||||
|
build( argv );
|
@ -1,50 +1,85 @@
|
|||||||
/**
|
/**
|
||||||
* Special concat/build task to handle various jQuery build requirements
|
* Special build task to handle various jQuery build requirements.
|
||||||
* Concats AMD modules, removes their definitions,
|
* Compiles JS modules into one bundle, sets the custom AMD name,
|
||||||
* and includes/excludes specified modules
|
* and includes/excludes specified modules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = function( grunt ) {
|
const fs = require( "fs" );
|
||||||
var fs = require( "fs" ),
|
const path = require( "path" );
|
||||||
requirejs = require( "requirejs" ),
|
const util = require( "util" );
|
||||||
slimBuildFlags = require( "./lib/slim-build-flags" ),
|
const exec = util.promisify( require( "child_process" ).exec );
|
||||||
srcFolder = __dirname + "/../../src/",
|
const requirejs = require( "requirejs" );
|
||||||
rdefineEnd = /\}\s*?\);[^}\w]*$/,
|
const excludedFromSlim = require( "./lib/slim-exclude" );
|
||||||
read = function( fileName ) {
|
const pkg = require( "../../package.json" );
|
||||||
return grunt.file.read( srcFolder + fileName );
|
const isCleanWorkingDir = require( "./lib/isCleanWorkingDir" );
|
||||||
|
const minify = require( "./minify" );
|
||||||
|
const getTimestamp = require( "./lib/getTimestamp" );
|
||||||
|
const verifyNodeVersion = require( "./lib/verifyNodeVersion" );
|
||||||
|
const srcFolder = path.resolve( __dirname, "../../src" );
|
||||||
|
|
||||||
|
const rdefineEnd = /\}\s*?\);[^}\w]*$/;
|
||||||
|
|
||||||
|
const minimum = [ "core" ];
|
||||||
|
|
||||||
|
// Exclude specified modules if the module matching the key is removed
|
||||||
|
const removeWith = {
|
||||||
|
ajax: [ "manipulation/_evalUrl", "deprecated/ajax-event-alias" ],
|
||||||
|
callbacks: [ "deferred" ],
|
||||||
|
css: [ "effects", "dimensions", "offset" ],
|
||||||
|
"css/showHide": [ "effects" ],
|
||||||
|
deferred: {
|
||||||
|
remove: [ "ajax", "effects", "queue", "core/ready" ],
|
||||||
|
include: [ "core/ready-no-deferred" ]
|
||||||
},
|
},
|
||||||
|
event: [ "deprecated/ajax-event-alias", "deprecated/event" ],
|
||||||
|
selector: [ "css/hiddenVisibleSelectors", "effects/animatedSelector" ]
|
||||||
|
};
|
||||||
|
|
||||||
|
async function read( filename ) {
|
||||||
|
return fs.promises.readFile( path.join( srcFolder, filename ), "utf8" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the src folder and file extension
|
||||||
|
// and ensure unix-style path separators
|
||||||
|
function moduleName( filename ) {
|
||||||
|
return filename
|
||||||
|
.replace( `${srcFolder}${path.sep}`, "" )
|
||||||
|
.replace( /\.js$/, "" )
|
||||||
|
.split( path.sep )
|
||||||
|
.join( path.posix.sep );
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readdirRecursive( dir, all = [] ) {
|
||||||
|
let files;
|
||||||
|
try {
|
||||||
|
files = await fs.promises.readdir( path.join( srcFolder, dir ), {
|
||||||
|
withFileTypes: true
|
||||||
|
} );
|
||||||
|
} catch ( e ) {
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
for ( const file of files ) {
|
||||||
|
const filepath = path.join( dir, file.name );
|
||||||
|
|
||||||
|
if ( file.isDirectory() ) {
|
||||||
|
all.push( ...( await readdirRecursive( filepath ) ) );
|
||||||
|
} else {
|
||||||
|
all.push( moduleName( filepath ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRequireConfig( { amd } = {} ) {
|
||||||
|
const wrapperSource = await read( "wrapper.js" );
|
||||||
|
|
||||||
// Catch `// @CODE` and subsequent comment lines event if they don't start
|
// Catch `// @CODE` and subsequent comment lines event if they don't start
|
||||||
// in the first column.
|
// in the first column.
|
||||||
wrapper = read( "wrapper.js" ).split( /[\x20\t]*\/\/ @CODE\n(?:[\x20\t]*\/\/[^\n]+\n)*/ ),
|
const wrapper = wrapperSource.split(
|
||||||
|
/[\x20\t]*\/\/ @CODE\n(?:[\x20\t]*\/\/[^\n]+\n)*/
|
||||||
config = {
|
);
|
||||||
baseUrl: "src",
|
|
||||||
name: "jquery",
|
|
||||||
|
|
||||||
// Allow strict mode
|
|
||||||
useStrict: true,
|
|
||||||
|
|
||||||
// We have multiple minify steps
|
|
||||||
optimize: "none",
|
|
||||||
|
|
||||||
// Include dependencies loaded with require
|
|
||||||
findNestedDependencies: true,
|
|
||||||
|
|
||||||
// Avoid inserting define() placeholder
|
|
||||||
skipModuleInsertion: true,
|
|
||||||
|
|
||||||
// Avoid breaking semicolons inserted by r.js
|
|
||||||
skipSemiColonInsertion: true,
|
|
||||||
wrap: {
|
|
||||||
start: wrapper[ 0 ].replace( /\/\*\s*eslint(?: |-).*\s*\*\/\n/, "" ),
|
|
||||||
end: wrapper[ 1 ]
|
|
||||||
},
|
|
||||||
rawText: {},
|
|
||||||
onBuildWrite: convert
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip all definitions generated by requirejs
|
* Strip all definitions generated by requirejs
|
||||||
@ -57,7 +92,6 @@ module.exports = function( grunt ) {
|
|||||||
* @param {String} contents The contents to be written (including their AMD wrappers)
|
* @param {String} contents The contents to be written (including their AMD wrappers)
|
||||||
*/
|
*/
|
||||||
function convert( name, path, contents ) {
|
function convert( name, path, contents ) {
|
||||||
var amdName;
|
|
||||||
|
|
||||||
// Convert var modules
|
// Convert var modules
|
||||||
if ( /.\/var\//.test( path.replace( process.cwd(), "" ) ) ) {
|
if ( /.\/var\//.test( path.replace( process.cwd(), "" ) ) ) {
|
||||||
@ -96,273 +130,214 @@ module.exports = function( grunt ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AMD Name
|
// AMD Name
|
||||||
if ( ( amdName = grunt.option( "amd" ) ) != null && /^exports\/amd$/.test( name ) ) {
|
if ( amd != null && /^exports\/amd$/.test( name ) ) {
|
||||||
if ( amdName ) {
|
if ( amd ) {
|
||||||
grunt.log.writeln( "Naming jQuery with AMD name: " + amdName );
|
console.log( "Naming jQuery with AMD name: " + amd );
|
||||||
} else {
|
} else {
|
||||||
grunt.log.writeln( "AMD name now anonymous" );
|
console.log( "AMD name now anonymous" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the comma for anonymous defines
|
// Remove the comma for anonymous defines
|
||||||
contents = contents
|
contents = contents
|
||||||
.replace( /(\s*)"jquery"(\,\s*)/, amdName ? "$1\"" + amdName + "\"$2" : "" );
|
.replace( /(\s*)"jquery"(\,\s*)/, amd ? "$1\"" + amd + "\"$2" : "" );
|
||||||
|
|
||||||
}
|
}
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
grunt.registerMultiTask(
|
return {
|
||||||
"build",
|
baseUrl: "src",
|
||||||
"Concatenate source, remove sub AMD definitions, " +
|
name: "jquery",
|
||||||
"(include/exclude modules with +/- flags), embed date/version",
|
|
||||||
function() {
|
|
||||||
var flag, index,
|
|
||||||
done = this.async(),
|
|
||||||
flags = this.flags,
|
|
||||||
optIn = flags[ "*" ],
|
|
||||||
name = grunt.option( "filename" ),
|
|
||||||
minimum = this.data.minimum,
|
|
||||||
removeWith = this.data.removeWith,
|
|
||||||
excluded = [],
|
|
||||||
included = [],
|
|
||||||
version = grunt.config( "pkg.version" ),
|
|
||||||
|
|
||||||
/**
|
// Allow strict mode
|
||||||
* Recursively calls the excluder to remove on all modules in the list
|
useStrict: true,
|
||||||
* @param {Array} list
|
|
||||||
* @param {String} [prepend] Prepend this to the module name.
|
|
||||||
* Indicates we're walking a directory
|
|
||||||
*/
|
|
||||||
excludeList = function( list, prepend ) {
|
|
||||||
if ( list ) {
|
|
||||||
prepend = prepend ? prepend + "/" : "";
|
|
||||||
list.forEach( function( module ) {
|
|
||||||
|
|
||||||
// Exclude var modules as well
|
// We have multiple minify steps
|
||||||
if ( module === "var" ) {
|
optimize: "none",
|
||||||
excludeList(
|
|
||||||
fs.readdirSync( srcFolder + prepend + module ), prepend + module
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( prepend ) {
|
|
||||||
|
|
||||||
// Skip if this is not a js file and we're walking files in a dir
|
// Include dependencies loaded with require
|
||||||
if ( !( module = /([\w-\/]+)\.js$/.exec( module ) ) ) {
|
findNestedDependencies: true,
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepend folder name if passed
|
// Avoid inserting define() placeholder
|
||||||
// Remove .js extension
|
skipModuleInsertion: true,
|
||||||
module = prepend + module[ 1 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid infinite recursion
|
// Avoid breaking semicolons inserted by r.js
|
||||||
if ( excluded.indexOf( module ) === -1 ) {
|
skipSemiColonInsertion: true,
|
||||||
excluder( "-" + module );
|
wrap: {
|
||||||
}
|
start: wrapper[ 0 ].replace( /\/\*\s*eslint(?: |-).*\s*\*\/\n/, "" ),
|
||||||
} );
|
end: wrapper[ 1 ]
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
rawText: {},
|
||||||
/**
|
onBuildWrite: convert
|
||||||
* Adds the specified module to the excluded or included list, depending on the flag
|
};
|
||||||
* @param {String} flag A module path relative to
|
|
||||||
* the src directory starting with + or - to indicate
|
|
||||||
* whether it should be included or excluded
|
|
||||||
*/
|
|
||||||
excluder = function( flag ) {
|
|
||||||
var additional,
|
|
||||||
m = /^(\+|-|)([\w\/-]+)$/.exec( flag ),
|
|
||||||
exclude = m[ 1 ] === "-",
|
|
||||||
module = m[ 2 ];
|
|
||||||
|
|
||||||
// Recognize the legacy `sizzle` alias
|
|
||||||
if ( module === "sizzle" ) {
|
|
||||||
module = "selector";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( exclude ) {
|
function unique( array ) {
|
||||||
|
return [ ...new Set( array ) ];
|
||||||
|
}
|
||||||
|
|
||||||
// Can't exclude certain modules
|
async function checkExclude( exclude, include ) {
|
||||||
if ( minimum.indexOf( module ) === -1 ) {
|
const included = [ ...include ];
|
||||||
|
const excluded = [ ...exclude ];
|
||||||
|
|
||||||
// Add to excluded
|
for ( const module of exclude ) {
|
||||||
if ( excluded.indexOf( module ) === -1 ) {
|
if ( minimum.indexOf( module ) !== -1 ) {
|
||||||
grunt.log.writeln( flag );
|
throw new Error( `Module \"${module}\" is a minimum requirement.` );
|
||||||
excluded.push( module );
|
}
|
||||||
|
|
||||||
// Exclude all files in the folder of the same name
|
// Exclude all files in the dir of the same name
|
||||||
// These are the removable dependencies
|
// These are the removable dependencies
|
||||||
// It's fine if the directory is not there
|
// It's fine if the directory is not there
|
||||||
try {
|
|
||||||
|
|
||||||
// `selector` is a special case as we don't just remove
|
// `selector` is a special case as we don't just remove
|
||||||
// the module, but we replace it with `selector-native`
|
// the module, but we replace it with `selector-native`
|
||||||
// which re-uses parts of the `src/selector` folder.
|
// which re-uses parts of the `src/selector` folder.
|
||||||
if ( module !== "selector" ) {
|
// "sizzle" is legacy for selector
|
||||||
excludeList(
|
if ( module !== "selector" && module !== "sizzle" ) {
|
||||||
fs.readdirSync( `${ srcFolder }/${ module }` ),
|
const files = await readdirRecursive( module );
|
||||||
module
|
excluded.push( ...files );
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch ( e ) {
|
|
||||||
grunt.verbose.writeln( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
additional = removeWith[ module ];
|
|
||||||
|
|
||||||
// Check removeWith list
|
// Check removeWith list
|
||||||
|
const additional = removeWith[ module ];
|
||||||
if ( additional ) {
|
if ( additional ) {
|
||||||
excludeList( additional.remove || additional );
|
const [ additionalExcluded, additionalIncluded ] = await checkExclude(
|
||||||
if ( additional.include ) {
|
additional.remove || additional,
|
||||||
included = included.concat( additional.include );
|
additional.include || []
|
||||||
grunt.log.writeln( "+" + additional.include );
|
);
|
||||||
|
excluded.push( ...additionalExcluded );
|
||||||
|
included.push( ...additionalIncluded );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
grunt.log.error( "Module \"" + module + "\" is a minimum requirement." );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
grunt.log.writeln( flag );
|
|
||||||
included.push( module );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Filename can be passed to the command line using
|
|
||||||
// command line options
|
|
||||||
// e.g. grunt build --filename=jquery-custom.js
|
|
||||||
name = name ? ( "dist/" + name ) : this.data.dest;
|
|
||||||
|
|
||||||
// append commit id to version
|
|
||||||
if ( process.env.COMMIT ) {
|
|
||||||
version += " " + process.env.COMMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// figure out which files to exclude based on these rules in this order:
|
return [ unique( excluded ), unique( included ) ];
|
||||||
// dependency explicit exclude
|
|
||||||
// > explicit exclude
|
|
||||||
// > explicit include
|
|
||||||
// > dependency implicit exclude
|
|
||||||
// > implicit exclude
|
|
||||||
// examples:
|
|
||||||
// * none (implicit exclude)
|
|
||||||
// *:* all (implicit include)
|
|
||||||
// *:*:-css all except css and dependents (explicit > implicit)
|
|
||||||
// *:*:-css:+effects same (excludes effects because explicit include is
|
|
||||||
// trumped by explicit exclude of dependency)
|
|
||||||
// *:+effects none except effects and its dependencies
|
|
||||||
// (explicit include trumps implicit exclude of dependency)
|
|
||||||
delete flags[ "*" ];
|
|
||||||
for ( flag in flags ) {
|
|
||||||
excluder( flag );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle full selector module exclusion.
|
async function build( {
|
||||||
// Replace with selector-native.
|
amd,
|
||||||
if ( excluded.indexOf( "selector" ) > -1 ) {
|
dir = "dist",
|
||||||
config.rawText.selector = "define([ \"./selector-native\" ]);";
|
exclude = [],
|
||||||
|
filename = "jquery.js",
|
||||||
|
include = [],
|
||||||
|
slim = false,
|
||||||
|
version
|
||||||
|
} = {} ) {
|
||||||
|
|
||||||
|
// Add the short commit hash to the version string
|
||||||
|
// when the version is not for a release.
|
||||||
|
if ( !version ) {
|
||||||
|
const { stdout } = await exec( "git rev-parse --short HEAD" );
|
||||||
|
const isClean = await isCleanWorkingDir();
|
||||||
|
|
||||||
|
// Add "+SHA" if the version is not set.
|
||||||
|
// Add ".dirty" as well if the working dir is not clean.
|
||||||
|
version = `${pkg.version}+${stdout.trim()}${isClean ? "" : ".dirty"}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await fs.promises.mkdir( dir, { recursive: true } );
|
||||||
|
|
||||||
|
// Exclude slim modules when slim is true
|
||||||
|
const [ excluded, included ] = await checkExclude(
|
||||||
|
slim ? exclude.concat( excludedFromSlim ) : exclude,
|
||||||
|
include
|
||||||
|
);
|
||||||
|
const config = await getRequireConfig( { amd } );
|
||||||
|
|
||||||
// Replace exports/global with a noop noConflict
|
// Replace exports/global with a noop noConflict
|
||||||
if ( ( index = excluded.indexOf( "exports/global" ) ) > -1 ) {
|
if ( excluded.includes( "exports/global" ) ) {
|
||||||
|
const index = excluded.indexOf( "exports/global" );
|
||||||
config.rawText[ "exports/global" ] = "define( [\n\t\"../core\"\n], " +
|
config.rawText[ "exports/global" ] = "define( [\n\t\"../core\"\n], " +
|
||||||
"function( jQuery ) {\n\tjQuery.noConflict = function() {};\n} );";
|
"function( jQuery ) {\n\tjQuery.noConflict = function() {};\n} );";
|
||||||
excluded.splice( index, 1 );
|
excluded.splice( index, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
grunt.verbose.writeflags( excluded, "Excluded" );
|
// "sizzle" is legacy for selector
|
||||||
grunt.verbose.writeflags( included, "Included" );
|
if ( excluded.indexOf( "selector" ) > -1 || excluded.indexOf( "sizzle" ) > -1 ) {
|
||||||
|
config.rawText.selector = "define( [ \"./selector-native\" ] );";
|
||||||
|
}
|
||||||
|
|
||||||
// append excluded modules to version
|
if ( excluded.length ) {
|
||||||
|
|
||||||
|
// Append excluded modules to version.
|
||||||
|
// Skip adding exclusions for slim builds.
|
||||||
|
// Don't worry about semver syntax for these.
|
||||||
if ( excluded.length ) {
|
if ( excluded.length ) {
|
||||||
version += " -" + excluded.join( ",-" );
|
version += " -" + excluded.join( ",-" );
|
||||||
|
}
|
||||||
// set pkg.version to version with excludes, so minified file picks it up
|
|
||||||
grunt.config.set( "pkg.version", version );
|
|
||||||
grunt.verbose.writeln( "Version changed to " + version );
|
|
||||||
|
|
||||||
// Have to use shallow or core will get excluded since it is a dependency
|
// Have to use shallow or core will get excluded since it is a dependency
|
||||||
config.excludeShallow = excluded;
|
config.excludeShallow = excluded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( included.length ) {
|
||||||
config.include = included;
|
config.include = included;
|
||||||
|
|
||||||
|
// Append extra included modules to version.
|
||||||
|
if ( included.length ) {
|
||||||
|
version += " +" + included.join( ",+" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overwrite the default inclusions with the explicit ones provided
|
||||||
|
config.rawText.jquery = "define( [\n" +
|
||||||
|
included.map( module => "\t\"./" + module + "\"" ).join( ",\n" ) +
|
||||||
|
"\n] );";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle Final output from the optimizer
|
* Handle Final output from the optimizer
|
||||||
* @param {String} compiled
|
* @param {String} compiled
|
||||||
*/
|
*/
|
||||||
config.out = function( compiled ) {
|
config.out = async function( compiled ) {
|
||||||
compiled = compiled
|
const compiledContents = compiled
|
||||||
|
|
||||||
// Embed Version
|
// Embed Version
|
||||||
.replace( /@VERSION/g, version )
|
.replace( /@VERSION/g, version )
|
||||||
|
|
||||||
// Embed Date
|
// Embed Date
|
||||||
// yyyy-mm-ddThh:mmZ
|
// yyyy-mm-ddThh:mmZ
|
||||||
.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
|
.replace( /@DATE/g, new Date().toISOString().replace( /:\d+\.\d+Z$/, "Z" ) );
|
||||||
|
|
||||||
// Write concatenated source to file
|
// Write concatenated source to file
|
||||||
grunt.file.write( name, compiled );
|
await fs.promises.writeFile(
|
||||||
|
path.join( dir, filename ),
|
||||||
|
compiledContents
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Turn off opt-in if necessary
|
await new Promise( ( resolve, reject ) => {
|
||||||
if ( !optIn ) {
|
requirejs.optimize( config, () => {
|
||||||
|
|
||||||
// Overwrite the default inclusions with the explicit ones provided
|
// Wait a beat. For some reason, the write can
|
||||||
config.rawText.jquery = "define( [\n" +
|
// take a moment after this to complete in Node 10.
|
||||||
( included.length ?
|
setTimeout( resolve, 100 );
|
||||||
included.map( module => "\t\"./" + module + "\"" ).join( ",\n" ) :
|
}, ( error ) => {
|
||||||
"" ) +
|
console.error( error );
|
||||||
"\n] );";
|
reject( error );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
console.log( `[${getTimestamp()}] ${filename} v${version} created.` );
|
||||||
|
|
||||||
|
await minify( { filename, dir } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace dependencies and concatenate files
|
async function buildDefaultFiles( { version } = {} ) {
|
||||||
requirejs.optimize( config, function( response ) {
|
await Promise.all( [
|
||||||
grunt.verbose.writeln( response );
|
build( { version } ),
|
||||||
grunt.log.ok( "File '" + name + "' created." );
|
build( { filename: "jquery.slim.js", slim: true, version } )
|
||||||
done();
|
|
||||||
}, function( err ) {
|
|
||||||
done( err );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Special "alias" task to make custom build creation less grawlix-y
|
|
||||||
// Translation example
|
|
||||||
//
|
|
||||||
// grunt custom:+ajax,-dimensions,-effects,-offset
|
|
||||||
//
|
|
||||||
// Becomes:
|
|
||||||
//
|
|
||||||
// grunt build:*:*:+ajax:-dimensions:-effects:-offset
|
|
||||||
//
|
|
||||||
// There's also a special "slim" alias that resolves to the jQuery Slim build
|
|
||||||
// configuration:
|
|
||||||
//
|
|
||||||
// grunt custom:slim
|
|
||||||
grunt.registerTask( "custom", function() {
|
|
||||||
var args = this.args,
|
|
||||||
modules = args.length ?
|
|
||||||
args[ 0 ]
|
|
||||||
.split( "," )
|
|
||||||
|
|
||||||
// Replace "slim" with respective exclusions meant for
|
|
||||||
// the official slim build
|
|
||||||
.reduce( ( acc, elem ) => acc.concat(
|
|
||||||
elem === "slim" ?
|
|
||||||
slimBuildFlags :
|
|
||||||
[ elem ]
|
|
||||||
), [] )
|
|
||||||
|
|
||||||
.join( ":" ) :
|
|
||||||
"";
|
|
||||||
|
|
||||||
grunt.log.writeln( "Creating custom build...\n" );
|
|
||||||
grunt.task.run( [
|
|
||||||
"build:*:*" + ( modules ? ":" + modules : "" ),
|
|
||||||
"uglify",
|
|
||||||
"remove_map_comment",
|
|
||||||
"dist"
|
|
||||||
] );
|
] );
|
||||||
|
|
||||||
|
// Earlier Node.js versions do not support the ESM format.
|
||||||
|
if ( !verifyNodeVersion() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { compareSize } = await import( "./compare_size.mjs" );
|
||||||
|
return compareSize( {
|
||||||
|
files: [
|
||||||
|
"dist/jquery.min.js",
|
||||||
|
"dist/jquery.slim.min.js"
|
||||||
|
]
|
||||||
} );
|
} );
|
||||||
};
|
}
|
||||||
|
|
||||||
|
module.exports = { build, buildDefaultFiles };
|
||||||
|
174
build/tasks/compare_size.mjs
Normal file
174
build/tasks/compare_size.mjs
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import chalk from "chalk";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
import zlib from "node:zlib";
|
||||||
|
import { exec as nodeExec } from "node:child_process";
|
||||||
|
import isCleanWorkingDir from "./lib/isCleanWorkingDir.js";
|
||||||
|
|
||||||
|
const VERSION = 1;
|
||||||
|
|
||||||
|
const gzip = promisify( zlib.gzip );
|
||||||
|
const exec = promisify( nodeExec );
|
||||||
|
|
||||||
|
async function getBranchName() {
|
||||||
|
const { stdout } = await exec( "git rev-parse --abbrev-ref HEAD" );
|
||||||
|
return stdout.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCommitHash() {
|
||||||
|
const { stdout } = await exec( "git rev-parse HEAD" );
|
||||||
|
return stdout.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBranchHeader( branch, commit ) {
|
||||||
|
let branchHeader = branch.trim();
|
||||||
|
if ( commit ) {
|
||||||
|
branchHeader = chalk.bold( branchHeader ) + chalk.gray( ` @${commit}` );
|
||||||
|
} else {
|
||||||
|
branchHeader = chalk.italic( branchHeader );
|
||||||
|
}
|
||||||
|
return branchHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCache( loc ) {
|
||||||
|
let cache;
|
||||||
|
try {
|
||||||
|
const contents = await fs.promises.readFile( loc, "utf8" );
|
||||||
|
cache = JSON.parse( contents );
|
||||||
|
} catch ( err ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastRun = cache[ " last run" ];
|
||||||
|
if ( !lastRun || !lastRun.meta || lastRun.meta.version !== VERSION ) {
|
||||||
|
console.log( "Compare cache version mismatch. Rewriting..." );
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheResults( results ) {
|
||||||
|
const files = Object.create( null );
|
||||||
|
results.forEach( function( result ) {
|
||||||
|
files[ result.filename ] = {
|
||||||
|
raw: result.raw,
|
||||||
|
gz: result.gz
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCache( loc, cache ) {
|
||||||
|
return fs.promises.writeFile( loc, JSON.stringify( cache ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareSizes( existing, current, padLength ) {
|
||||||
|
if ( typeof current !== "number" ) {
|
||||||
|
return chalk.grey( `${existing}`.padStart( padLength ) );
|
||||||
|
}
|
||||||
|
const delta = current - existing;
|
||||||
|
if ( delta > 0 ) {
|
||||||
|
return chalk.red( `+${delta}`.padStart( padLength ) );
|
||||||
|
}
|
||||||
|
return chalk.green( `${delta}`.padStart( padLength ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function compareSize( { cache = ".sizecache.json", files } = {} ) {
|
||||||
|
if ( !files || !files.length ) {
|
||||||
|
throw new Error( "No files specified" );
|
||||||
|
}
|
||||||
|
|
||||||
|
const branch = await getBranchName();
|
||||||
|
const commit = await getCommitHash();
|
||||||
|
const sizeCache = await getCache( cache );
|
||||||
|
|
||||||
|
let rawPadLength = 0;
|
||||||
|
let gzPadLength = 0;
|
||||||
|
const results = await Promise.all(
|
||||||
|
files.map( async function( filename ) {
|
||||||
|
|
||||||
|
let contents = await fs.promises.readFile( filename, "utf8" );
|
||||||
|
|
||||||
|
// Remove the short SHA and .dirty from comparisons.
|
||||||
|
// The short SHA so commits can be compared against each other
|
||||||
|
// and .dirty to compare with the existing branch during development.
|
||||||
|
const sha = /jQuery v\d+.\d+.\d+(?:-\w+)?\+(?:slim.)?([^ \.]+(?:\.dirty)?)/.exec( contents )[ 1 ];
|
||||||
|
contents = contents.replace( new RegExp( sha, "g" ), "" );
|
||||||
|
|
||||||
|
const size = Buffer.byteLength( contents, "utf8" );
|
||||||
|
const gzippedSize = ( await gzip( contents ) ).length;
|
||||||
|
|
||||||
|
// Add one to give space for the `+` or `-` in the comparison
|
||||||
|
rawPadLength = Math.max( rawPadLength, size.toString().length + 1 );
|
||||||
|
gzPadLength = Math.max( gzPadLength, gzippedSize.toString().length + 1 );
|
||||||
|
|
||||||
|
return { filename, raw: size, gz: gzippedSize };
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
|
||||||
|
const sizeHeader = "raw".padStart( rawPadLength ) +
|
||||||
|
"gz".padStart( gzPadLength + 1 ) +
|
||||||
|
" Filename";
|
||||||
|
|
||||||
|
const sizes = results.map( function( result ) {
|
||||||
|
const rawSize = result.raw.toString().padStart( rawPadLength );
|
||||||
|
const gzSize = result.gz.toString().padStart( gzPadLength );
|
||||||
|
return `${rawSize} ${gzSize} ${result.filename}`;
|
||||||
|
} );
|
||||||
|
|
||||||
|
const comparisons = Object.keys( sizeCache ).map( function( branch ) {
|
||||||
|
const meta = sizeCache[ branch ].meta || {};
|
||||||
|
const commit = meta.commit;
|
||||||
|
|
||||||
|
const files = sizeCache[ branch ].files;
|
||||||
|
const branchSizes = Object.keys( files ).map( function( filename ) {
|
||||||
|
const branchResult = files[ filename ];
|
||||||
|
const compareResult = results.find( function( result ) {
|
||||||
|
return result.filename === filename;
|
||||||
|
} ) || {};
|
||||||
|
|
||||||
|
const compareRaw = compareSizes( branchResult.raw, compareResult.raw, rawPadLength );
|
||||||
|
const compareGz = compareSizes( branchResult.gz, compareResult.gz, gzPadLength );
|
||||||
|
return `${compareRaw} ${compareGz} ${filename}`;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return [
|
||||||
|
"", // New line before each branch
|
||||||
|
getBranchHeader( branch, commit ),
|
||||||
|
sizeHeader,
|
||||||
|
...branchSizes
|
||||||
|
].join( "\n" );
|
||||||
|
} );
|
||||||
|
|
||||||
|
const output = [
|
||||||
|
"", // Opening new line
|
||||||
|
chalk.bold( "Sizes" ),
|
||||||
|
sizeHeader,
|
||||||
|
...sizes,
|
||||||
|
...comparisons,
|
||||||
|
"" // Closing new line
|
||||||
|
].join( "\n" );
|
||||||
|
|
||||||
|
console.log( output );
|
||||||
|
|
||||||
|
// Always save the last run
|
||||||
|
// Save version under last run
|
||||||
|
sizeCache[ " last run" ] = {
|
||||||
|
meta: { version: VERSION },
|
||||||
|
files: cacheResults( results )
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only save cache for the current branch
|
||||||
|
// if the working directory is clean.
|
||||||
|
if ( await isCleanWorkingDir() ) {
|
||||||
|
sizeCache[ branch ] = {
|
||||||
|
meta: { commit },
|
||||||
|
files: cacheResults( results )
|
||||||
|
};
|
||||||
|
console.log( `Saved cache for ${branch}.` );
|
||||||
|
}
|
||||||
|
|
||||||
|
await saveCache( cache, sizeCache );
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
@ -1,71 +1,31 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = function( grunt ) {
|
// Process files for distribution.
|
||||||
const fs = require( "fs" );
|
module.exports = function processForDist( text, filename ) {
|
||||||
const filename = grunt.option( "filename" );
|
if ( !text ) {
|
||||||
const distPaths = [
|
throw new Error( "text required for processForDist" );
|
||||||
`dist/${ filename }`,
|
}
|
||||||
`dist/${ filename.replace( ".js", ".min.js" ) }`,
|
|
||||||
`dist/${ filename.replace( ".js", ".min.map" ) }`
|
|
||||||
];
|
|
||||||
|
|
||||||
// Process files for distribution
|
if ( !filename ) {
|
||||||
grunt.registerTask( "dist", function() {
|
throw new Error( "filename required for processForDist" );
|
||||||
let stored, flags, paths, nonascii;
|
}
|
||||||
|
|
||||||
// Check for stored destination paths
|
|
||||||
// ( set in dist/.destination.json )
|
|
||||||
stored = Object.keys( grunt.config( "dst" ) );
|
|
||||||
|
|
||||||
// Allow command line input as well
|
|
||||||
flags = Object.keys( this.flags );
|
|
||||||
|
|
||||||
// Combine all output target paths
|
|
||||||
paths = [].concat( stored, flags ).filter( function( path ) {
|
|
||||||
return path !== "*";
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Ensure the dist files are pure ASCII
|
|
||||||
nonascii = false;
|
|
||||||
|
|
||||||
distPaths.forEach( function( filename ) {
|
|
||||||
let i, c;
|
|
||||||
const text = fs.readFileSync( filename, "utf8" );
|
|
||||||
|
|
||||||
// Ensure files use only \n for line endings, not \r\n
|
// Ensure files use only \n for line endings, not \r\n
|
||||||
if ( /\x0d\x0a/.test( text ) ) {
|
if ( /\x0d\x0a/.test( text ) ) {
|
||||||
grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" );
|
throw new Error( filename + ": Incorrect line endings (\\r\\n)" );
|
||||||
nonascii = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure only ASCII chars so script tags don't need a charset attribute
|
// Ensure only ASCII chars so script tags don't need a charset attribute
|
||||||
if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
|
if ( text.length !== Buffer.byteLength( text, "utf8" ) ) {
|
||||||
grunt.log.writeln( filename + ": Non-ASCII characters detected:" );
|
let message = filename + ": Non-ASCII characters detected:\n";
|
||||||
for ( i = 0; i < text.length; i++ ) {
|
for ( let i = 0; i < text.length; i++ ) {
|
||||||
c = text.charCodeAt( i );
|
const c = text.charCodeAt( i );
|
||||||
if ( c > 127 ) {
|
if ( c > 127 ) {
|
||||||
grunt.log.writeln( "- position " + i + ": " + c );
|
message += "- position " + i + ": " + c + "\n";
|
||||||
grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) );
|
message += "==> " + text.substring( i - 20, i + 20 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonascii = true;
|
throw new Error( message );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionally copy dist files to other locations
|
|
||||||
paths.forEach( function( path ) {
|
|
||||||
let created;
|
|
||||||
|
|
||||||
if ( !/\/$/.test( path ) ) {
|
|
||||||
path += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
created = path + filename.replace( "dist/", "" );
|
|
||||||
grunt.file.write( created, text );
|
|
||||||
grunt.log.writeln( "File '" + created + "' created." );
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
return !nonascii;
|
|
||||||
} );
|
|
||||||
};
|
};
|
||||||
|
9
build/tasks/lib/getTimestamp.js
Normal file
9
build/tasks/lib/getTimestamp.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = function getTimestamp() {
|
||||||
|
const now = new Date();
|
||||||
|
const hours = now.getHours().toString().padStart( 2, "0" );
|
||||||
|
const minutes = now.getMinutes().toString().padStart( 2, "0" );
|
||||||
|
const seconds = now.getSeconds().toString().padStart( 2, "0" );
|
||||||
|
return `${hours}:${minutes}:${seconds}`;
|
||||||
|
};
|
9
build/tasks/lib/isCleanWorkingDir.js
Normal file
9
build/tasks/lib/isCleanWorkingDir.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const util = require( "util" );
|
||||||
|
const exec = util.promisify( require( "child_process" ).exec );
|
||||||
|
|
||||||
|
module.exports = async function isCleanWorkingDir() {
|
||||||
|
const { stdout } = await exec( "git status --untracked-files=no --porcelain" );
|
||||||
|
return !stdout.trim();
|
||||||
|
};
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
// NOTE: keep it in sync with test/data/testinit.js
|
// NOTE: keep it in sync with test/data/testinit.js
|
||||||
module.exports = [
|
module.exports = [
|
||||||
"-ajax",
|
"ajax",
|
||||||
"-effects"
|
"effects"
|
||||||
];
|
];
|
@ -1,16 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
// Run Node with provided parameters: the first one being the Grunt
|
|
||||||
// done function and latter ones being files to be tested.
|
|
||||||
// See the comment in ../node_smoke_tests.js for more information.
|
|
||||||
module.exports = function spawnTest( done, command ) {
|
|
||||||
var spawn = require( "child_process" ).spawn;
|
|
||||||
|
|
||||||
spawn( command, {
|
|
||||||
stdio: "inherit",
|
|
||||||
shell: true
|
|
||||||
} )
|
|
||||||
.on( "close", function( code ) {
|
|
||||||
done( code === 0 );
|
|
||||||
} );
|
|
||||||
};
|
|
12
build/tasks/lib/verifyNodeVersion.js
Normal file
12
build/tasks/lib/verifyNodeVersion.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { version } = require( "process" );
|
||||||
|
const nodeV16OrNewer = !/^v1[0-5]\./.test( version );
|
||||||
|
|
||||||
|
module.exports = function verifyNodeVersion() {
|
||||||
|
if ( !nodeV16OrNewer ) {
|
||||||
|
console.log( "Old Node.js detected, task skipped..." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
83
build/tasks/minify.js
Normal file
83
build/tasks/minify.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const UglifyJS = require( "uglify-js" );
|
||||||
|
const fs = require( "fs" );
|
||||||
|
const path = require( "path" );
|
||||||
|
const processForDist = require( "./dist" );
|
||||||
|
const getTimestamp = require( "./lib/getTimestamp" );
|
||||||
|
|
||||||
|
const rjs = /\.js$/;
|
||||||
|
|
||||||
|
module.exports = async function minify( { dir, filename } ) {
|
||||||
|
const filepath = path.join( dir, filename );
|
||||||
|
const contents = await fs.promises.readFile( filepath, "utf8" );
|
||||||
|
const version = /jQuery JavaScript Library ([^\n]+)/.exec( contents )[ 1 ];
|
||||||
|
const banner = `/*! jQuery ${version}` +
|
||||||
|
" | (c) OpenJS Foundation and other contributors" +
|
||||||
|
" | jquery.org/license */";
|
||||||
|
|
||||||
|
const minFilename = filename.replace( rjs, ".min.js" );
|
||||||
|
const mapFilename = filename.replace( rjs, ".min.map" );
|
||||||
|
|
||||||
|
const { code, error, map: incompleteMap, warning } = UglifyJS.minify(
|
||||||
|
contents,
|
||||||
|
{
|
||||||
|
compress: {
|
||||||
|
hoist_funs: false,
|
||||||
|
loops: false,
|
||||||
|
|
||||||
|
// Support: IE <11
|
||||||
|
// typeofs transformation is unsafe for IE9-10
|
||||||
|
// See https://github.com/mishoo/UglifyJS2/issues/2198
|
||||||
|
typeofs: false
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
ascii_only: true,
|
||||||
|
|
||||||
|
// Support: Android 4.0 only
|
||||||
|
// UglifyJS 3 breaks Android 4.0 if this option is not enabled.
|
||||||
|
// This is in lieu of setting ie for all of mangle, compress, and output
|
||||||
|
ie8: true,
|
||||||
|
preamble: banner
|
||||||
|
},
|
||||||
|
sourceMap: {
|
||||||
|
filename: minFilename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( error ) {
|
||||||
|
throw new Error( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( warning ) {
|
||||||
|
console.warn( warning );
|
||||||
|
}
|
||||||
|
|
||||||
|
// The map's `sources` property is set to an array index.
|
||||||
|
// Fix it by setting it to the correct filename.
|
||||||
|
const map = JSON.stringify( {
|
||||||
|
...JSON.parse( incompleteMap ),
|
||||||
|
file: minFilename,
|
||||||
|
sources: [ filename ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
await Promise.all( [
|
||||||
|
fs.promises.writeFile(
|
||||||
|
path.join( dir, minFilename ),
|
||||||
|
code
|
||||||
|
),
|
||||||
|
fs.promises.writeFile(
|
||||||
|
path.join( dir, mapFilename ),
|
||||||
|
map
|
||||||
|
)
|
||||||
|
] );
|
||||||
|
|
||||||
|
// Always process files for dist
|
||||||
|
// Doing it here avoids extra file reads
|
||||||
|
processForDist( contents, filename );
|
||||||
|
processForDist( code, minFilename );
|
||||||
|
processForDist( map, mapFilename );
|
||||||
|
|
||||||
|
console.log( `[${getTimestamp()}] ${minFilename} ${version} with ${mapFilename} created.` );
|
||||||
|
};
|
@ -1,42 +1,42 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = ( grunt ) => {
|
|
||||||
const fs = require( "fs" );
|
const fs = require( "fs" );
|
||||||
const spawnTest = require( "./lib/spawn_test.js" );
|
const util = require( "util" );
|
||||||
const nodeV16OrNewer = !/^v1[0-5]\./.test( process.version );
|
const exec = util.promisify( require( "child_process" ).exec );
|
||||||
|
const verifyNodeVersion = require( "./lib/verifyNodeVersion" );
|
||||||
|
|
||||||
grunt.registerTask( "node_smoke_tests", function( jQueryModuleSpecifier = "./dist/jquery.js" ) {
|
if ( !verifyNodeVersion() ) {
|
||||||
if ( !nodeV16OrNewer ) {
|
|
||||||
grunt.log.writeln( "Old Node.js detected, running the task " +
|
|
||||||
`"node_smoke_tests:${ jQueryModuleSpecifier }" skipped...` );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const testsDir = "./test/node_smoke_tests";
|
|
||||||
const nodeSmokeTests = [];
|
|
||||||
|
|
||||||
// Fire up all tests defined in test/node_smoke_tests/*.js in spawned sub-processes.
|
// Fire up all tests defined in test/node_smoke_tests/*.js in spawned sub-processes.
|
||||||
// All the files under test/node_smoke_tests/*.js are supposed to exit with 0 code
|
// All the files under test/node_smoke_tests/*.js are supposed to exit with 0 code
|
||||||
// on success or another one on failure. Spawning in sub-processes is
|
// on success or another one on failure. Spawning in sub-processes is
|
||||||
// important so that the tests & the main process don't interfere with
|
// important so that the tests & the main process don't interfere with
|
||||||
// each other, e.g. so that they don't share the `require` cache.
|
// each other, e.g. so that they don't share the `require` cache.
|
||||||
|
|
||||||
fs.readdirSync( testsDir )
|
async function runTests( { module } ) {
|
||||||
.filter( ( testFilePath ) =>
|
const dir = "./test/node_smoke_tests";
|
||||||
fs.statSync( `${ testsDir }/${ testFilePath }` ).isFile() &&
|
const files = await fs.promises.readdir( dir, { withFileTypes: true } );
|
||||||
/\.[cm]?js$/.test( testFilePath )
|
const testFiles = files.filter( ( testFilePath ) => testFilePath.isFile() );
|
||||||
|
|
||||||
|
if ( !testFiles.length ) {
|
||||||
|
throw new Error( `No test files found for "${module}"` );
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
testFiles.map( ( testFile ) =>
|
||||||
|
exec( `node "${dir}/${testFile.name}" ${module}` )
|
||||||
)
|
)
|
||||||
.forEach( ( testFilePath ) => {
|
);
|
||||||
const taskName = `node_${ testFilePath.replace( /\.[cm]?js$/, "" ) }:${ jQueryModuleSpecifier }`;
|
console.log( `Node smoke tests passed for "${module}".` );
|
||||||
|
}
|
||||||
|
|
||||||
grunt.registerTask( taskName, function() {
|
async function runDefaultTests() {
|
||||||
spawnTest( this.async(), `node "${ testsDir }/${
|
await Promise.all( [
|
||||||
testFilePath }" ${ jQueryModuleSpecifier }` );
|
runTests( { module: "./dist/jquery.js" } ),
|
||||||
} );
|
runTests( { module: "./dist/jquery.slim.js" } )
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
nodeSmokeTests.push( taskName );
|
runDefaultTests();
|
||||||
} );
|
|
||||||
|
|
||||||
grunt.task.run( nodeSmokeTests );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
42
build/tasks/npmcopy.js
Normal file
42
build/tasks/npmcopy.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const fs = require( "fs" );
|
||||||
|
const path = require( "path" );
|
||||||
|
|
||||||
|
const projectDir = path.resolve( __dirname, "..", ".." );
|
||||||
|
|
||||||
|
const files = {
|
||||||
|
"bootstrap/bootstrap.css": "bootstrap/dist/css/bootstrap.css",
|
||||||
|
"bootstrap/bootstrap.min.css": "bootstrap/dist/css/bootstrap.min.css",
|
||||||
|
"bootstrap/bootstrap.min.css.map": "bootstrap/dist/css/bootstrap.min.css.map",
|
||||||
|
|
||||||
|
"core-js-bundle/core-js-bundle.js": "core-js-bundle/minified.js",
|
||||||
|
"core-js-bundle/LICENSE": "core-js-bundle/LICENSE",
|
||||||
|
|
||||||
|
"npo/npo.js": "native-promise-only/lib/npo.src.js",
|
||||||
|
|
||||||
|
"qunit/qunit.js": "qunit/qunit/qunit.js",
|
||||||
|
"qunit/qunit.css": "qunit/qunit/qunit.css",
|
||||||
|
"qunit/LICENSE.txt": "qunit/LICENSE.txt",
|
||||||
|
|
||||||
|
"requirejs/require.js": "requirejs/require.js",
|
||||||
|
|
||||||
|
"sinon/sinon.js": "sinon/pkg/sinon.js",
|
||||||
|
"sinon/LICENSE.txt": "sinon/LICENSE"
|
||||||
|
};
|
||||||
|
|
||||||
|
async function npmcopy() {
|
||||||
|
await fs.promises.mkdir( path.resolve( projectDir, "external" ), {
|
||||||
|
recursive: true
|
||||||
|
} );
|
||||||
|
for ( const [ dest, source ] of Object.entries( files ) ) {
|
||||||
|
const from = path.resolve( projectDir, "node_modules", source );
|
||||||
|
const to = path.resolve( projectDir, "external", dest );
|
||||||
|
const toDir = path.dirname( to );
|
||||||
|
await fs.promises.mkdir( toDir, { recursive: true } );
|
||||||
|
await fs.promises.copyFile( from, to );
|
||||||
|
console.log( `${source} → ${dest}` );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
npmcopy();
|
@ -1,27 +1,32 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = grunt => {
|
const { spawn } = require( "child_process" );
|
||||||
const timeout = 2000;
|
const verifyNodeVersion = require( "./lib/verifyNodeVersion" );
|
||||||
const spawnTest = require( "./lib/spawn_test.js" );
|
const path = require( "path" );
|
||||||
|
const os = require( "os" );
|
||||||
|
|
||||||
grunt.registerTask( "promises_aplus_tests",
|
if ( !verifyNodeVersion() ) {
|
||||||
[ "promises_aplus_tests:deferred", "promises_aplus_tests:when" ] );
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
grunt.registerTask( "promises_aplus_tests:deferred", function() {
|
const command = path.resolve(
|
||||||
spawnTest( this.async(),
|
__dirname,
|
||||||
"\"" + __dirname + "/../../node_modules/.bin/promises-aplus-tests\"" +
|
`../../node_modules/.bin/promises-aplus-tests${os.platform() === "win32" ? ".cmd" : ""}`
|
||||||
" test/promises_aplus_adapters/deferred.js" +
|
);
|
||||||
" --reporter dot" +
|
const args = [ "--reporter", "dot", "--timeout", "2000" ];
|
||||||
" --timeout " + timeout
|
const tests = [
|
||||||
|
"test/promises_aplus_adapters/deferred.js",
|
||||||
|
"test/promises_aplus_adapters/when.js"
|
||||||
|
];
|
||||||
|
|
||||||
|
async function runTests() {
|
||||||
|
tests.forEach( ( test ) => {
|
||||||
|
spawn(
|
||||||
|
command,
|
||||||
|
[ test ].concat( args ),
|
||||||
|
{ stdio: "inherit" }
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
grunt.registerTask( "promises_aplus_tests:when", function() {
|
runTests();
|
||||||
spawnTest( this.async(),
|
|
||||||
"\"" + __dirname + "/../../node_modules/.bin/promises-aplus-tests\"" +
|
|
||||||
" test/promises_aplus_adapters/when.js" +
|
|
||||||
" --reporter dot" +
|
|
||||||
" --timeout " + timeout
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
17
build/tasks/qunit-fixture.js
Normal file
17
build/tasks/qunit-fixture.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const fs = require( "fs" );
|
||||||
|
|
||||||
|
async function generateFixture() {
|
||||||
|
const fixture = await fs.promises.readFile( "./test/data/qunit-fixture.html", "utf8" );
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
"./test/data/qunit-fixture.js",
|
||||||
|
"// Generated by build/tasks/qunit-fixture.js\n" +
|
||||||
|
"QUnit.config.fixture = " +
|
||||||
|
JSON.stringify( fixture.replace( /\r\n/g, "\n" ) ) +
|
||||||
|
";\n"
|
||||||
|
);
|
||||||
|
console.log( "Updated ./test/data/qunit-fixture.js" );
|
||||||
|
}
|
||||||
|
|
||||||
|
generateFixture();
|
@ -1,22 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
var fs = require( "fs" );
|
|
||||||
|
|
||||||
module.exports = function( grunt ) {
|
|
||||||
grunt.registerTask( "qunit_fixture", function() {
|
|
||||||
var dest = "./test/data/qunit-fixture.js";
|
|
||||||
fs.writeFileSync(
|
|
||||||
dest,
|
|
||||||
"// Generated by build/tasks/qunit_fixture.js\n" +
|
|
||||||
"QUnit.config.fixture = " +
|
|
||||||
JSON.stringify(
|
|
||||||
fs.readFileSync(
|
|
||||||
"./test/data/qunit-fixture.html",
|
|
||||||
"utf8"
|
|
||||||
).toString().replace( /\r\n/g, "\n" )
|
|
||||||
) +
|
|
||||||
";\n"
|
|
||||||
);
|
|
||||||
grunt.log.ok( "Updated " + dest + "." );
|
|
||||||
} );
|
|
||||||
};
|
|
@ -1,17 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
var fs = require( "fs" );
|
|
||||||
|
|
||||||
module.exports = function( grunt ) {
|
|
||||||
var config = grunt.config( "uglify.all.files" );
|
|
||||||
grunt.registerTask( "remove_map_comment", function() {
|
|
||||||
var minLoc = grunt.config.process( Object.keys( config )[ 0 ] );
|
|
||||||
|
|
||||||
// Remove the source map comment; it causes way too many problems.
|
|
||||||
// The map file is still generated for manual associations
|
|
||||||
// https://github.com/jquery/jquery/issues/1707
|
|
||||||
var text = fs.readFileSync( minLoc, "utf8" )
|
|
||||||
.replace( /\/\/# sourceMappingURL=\S+/, "" );
|
|
||||||
fs.writeFileSync( minLoc, text );
|
|
||||||
} );
|
|
||||||
};
|
|
35
dist/.eslintrc.json
vendored
35
dist/.eslintrc.json
vendored
@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 5,
|
|
||||||
"sourceType": "script"
|
|
||||||
},
|
|
||||||
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "jquery{,.slim}.min.js",
|
|
||||||
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 5,
|
|
||||||
"sourceType": "script"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"files": "jquery{,.slim}.js",
|
|
||||||
"extends": "../.eslintrc-browser.json",
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
|
|
||||||
// That is okay for the built version
|
|
||||||
"no-multiple-empty-lines": "off",
|
|
||||||
|
|
||||||
// When custom compilation is used, the version string
|
|
||||||
// can get large. Accept that in the built version.
|
|
||||||
"max-len": "off",
|
|
||||||
"one-var": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
271
eslint.config.js
Normal file
271
eslint.config.js
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const jqueryConfig = require( "eslint-config-jquery" );
|
||||||
|
const globals = require( "globals" );
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
|
||||||
|
// Only global ignores will bypass the parser
|
||||||
|
// and avoid JS parsing errors
|
||||||
|
// See https://github.com/eslint/eslint/discussions/17412
|
||||||
|
ignores: [
|
||||||
|
"external",
|
||||||
|
"test/data/json_obj.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"eslint.config.js",
|
||||||
|
"Gruntfile.js",
|
||||||
|
"test/node_smoke_tests/**",
|
||||||
|
"test/promises_aplus_adapters/**",
|
||||||
|
"test/middleware-mockserver.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node
|
||||||
|
},
|
||||||
|
sourceType: "commonjs"
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...jqueryConfig.rules,
|
||||||
|
strict: [ "error", "global" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Source
|
||||||
|
{
|
||||||
|
files: [ "src/**" ],
|
||||||
|
languageOptions: {
|
||||||
|
|
||||||
|
// The browser env is not enabled on purpose so that code takes
|
||||||
|
// all browser-only globals from window instead of assuming
|
||||||
|
// they're available as globals. This makes it possible to use
|
||||||
|
// jQuery with tools like jsdom which provide a custom window
|
||||||
|
// implementation.
|
||||||
|
globals: {
|
||||||
|
define: false,
|
||||||
|
window: false
|
||||||
|
},
|
||||||
|
sourceType: "commonjs"
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...jqueryConfig.rules,
|
||||||
|
indent: [
|
||||||
|
"error",
|
||||||
|
"tab",
|
||||||
|
{
|
||||||
|
outerIIFEBody: 0,
|
||||||
|
|
||||||
|
// Ignore the top level function defining an AMD module
|
||||||
|
ignoredNodes: [
|
||||||
|
"Program > ExpressionStatement > CallExpression > :last-child > *"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"one-var": [ "error", { var: "always" } ],
|
||||||
|
strict: [ "error", "function" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [ "src/selector.js" ],
|
||||||
|
rules: {
|
||||||
|
indent: "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [ "src/wrapper.js" ],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
jQuery: false,
|
||||||
|
module: true
|
||||||
|
},
|
||||||
|
sourceType: "script"
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
indent: [
|
||||||
|
"error",
|
||||||
|
"tab",
|
||||||
|
{
|
||||||
|
|
||||||
|
// Unlike other codes, "wrapper.js" is implemented in UMD.
|
||||||
|
// So it required a specific exception for jQuery's UMD
|
||||||
|
// Code Style. This makes that indentation check is not
|
||||||
|
// performed for 1 depth of outer FunctionExpressions
|
||||||
|
ignoredNodes: [
|
||||||
|
"Program > ExpressionStatement > CallExpression > :last-child > *"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [ "src/exports/amd.js" ],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
define: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Tests
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"test/**"
|
||||||
|
],
|
||||||
|
ignores: [
|
||||||
|
"test/data/jquery-1.9.1.js",
|
||||||
|
"test/data/badcall.js",
|
||||||
|
"test/data/badjson.js",
|
||||||
|
"test/data/support/csp.js",
|
||||||
|
"test/data/support/getComputedSupport.js",
|
||||||
|
"test/data/core/jquery-iterability-transpiled.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
require: false,
|
||||||
|
Promise: false,
|
||||||
|
Symbol: false,
|
||||||
|
trustedTypes: false,
|
||||||
|
QUnit: false,
|
||||||
|
ajaxTest: false,
|
||||||
|
testIframe: false,
|
||||||
|
createDashboardXML: false,
|
||||||
|
createWithFriesXML: false,
|
||||||
|
createXMLFragment: false,
|
||||||
|
includesModule: false,
|
||||||
|
moduleTeardown: false,
|
||||||
|
url: false,
|
||||||
|
q: false,
|
||||||
|
jQuery: true,
|
||||||
|
sinon: true,
|
||||||
|
amdDefined: true,
|
||||||
|
fireNative: true,
|
||||||
|
Globals: true,
|
||||||
|
hasPHP: true,
|
||||||
|
isLocal: true,
|
||||||
|
supportjQuery: true,
|
||||||
|
originaljQuery: true,
|
||||||
|
$: true,
|
||||||
|
original$: true,
|
||||||
|
baseURL: true,
|
||||||
|
externalHost: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...jqueryConfig.rules,
|
||||||
|
strict: [ "error", "function" ],
|
||||||
|
|
||||||
|
// See https://github.com/eslint/eslint/issues/2342
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
|
||||||
|
// Too many errors
|
||||||
|
"max-len": "off",
|
||||||
|
camelcase: "off",
|
||||||
|
"one-var": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"test/data/testrunner.js",
|
||||||
|
"test/data/core/jquery-iterability-transpiled-es6.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
sourceType: "script"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"test/unit/deferred.js"
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
|
||||||
|
// Deferred tests set strict mode for certain tests
|
||||||
|
strict: "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"test/node_smoke_tests/**",
|
||||||
|
"test/promises_aplus_adapters/**",
|
||||||
|
"test/middleware-mockserver.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
...globals.es2021
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
strict: [ "error", "global" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"build/**",
|
||||||
|
"test/data/testinit.js",
|
||||||
|
"test/data/testinit-jsdom.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
...globals.es2021
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...jqueryConfig.rules,
|
||||||
|
strict: [ "error", "global" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"build/**/*.js",
|
||||||
|
"test/data/testinit.js",
|
||||||
|
"test/data/testinit-jsdom.js"
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
sourceType: "commonjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
"dist/jquery.js",
|
||||||
|
"dist/jquery.slim.js"
|
||||||
|
],
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
...globals.es2021,
|
||||||
|
define: false,
|
||||||
|
module: false,
|
||||||
|
Symbol: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
...jqueryConfig.rules,
|
||||||
|
|
||||||
|
// That is okay for the built version
|
||||||
|
"no-multiple-empty-lines": "off",
|
||||||
|
|
||||||
|
// When custom compilation is used, the version string
|
||||||
|
// can get large. Accept that in the built version.
|
||||||
|
"max-len": "off",
|
||||||
|
"one-var": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
12071
external/bootstrap/bootstrap.css
vendored
12071
external/bootstrap/bootstrap.css
vendored
File diff suppressed because it is too large
Load Diff
6
external/bootstrap/bootstrap.min.css
vendored
6
external/bootstrap/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
1
external/bootstrap/bootstrap.min.css.map
vendored
1
external/bootstrap/bootstrap.min.css.map
vendored
File diff suppressed because one or more lines are too long
19
external/core-js/LICENSE.txt
vendored
19
external/core-js/LICENSE.txt
vendored
@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2014-2019 Denis Pushkarev
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
10
external/core-js/core-js.js
vendored
10
external/core-js/core-js.js
vendored
File diff suppressed because one or more lines are too long
373
external/npo/npo.js
vendored
373
external/npo/npo.js
vendored
@ -1,373 +0,0 @@
|
|||||||
/*! Native Promise Only
|
|
||||||
v0.8.1 (c) Kyle Simpson
|
|
||||||
MIT License: http://getify.mit-license.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function UMD(name,context,definition){
|
|
||||||
// special form of UMD for polyfilling across evironments
|
|
||||||
context[name] = context[name] || definition();
|
|
||||||
if (typeof module != "undefined" && module.exports) { module.exports = context[name]; }
|
|
||||||
else if (typeof define == "function" && define.amd) { define(function $AMD$(){ return context[name]; }); }
|
|
||||||
})("Promise",typeof global != "undefined" ? global : this,function DEF(){
|
|
||||||
/*jshint validthis:true */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var builtInProp, cycle, scheduling_queue,
|
|
||||||
ToString = Object.prototype.toString,
|
|
||||||
timer = (typeof setImmediate != "undefined") ?
|
|
||||||
function timer(fn) { return setImmediate(fn); } :
|
|
||||||
setTimeout
|
|
||||||
;
|
|
||||||
|
|
||||||
// dammit, IE8.
|
|
||||||
try {
|
|
||||||
Object.defineProperty({},"x",{});
|
|
||||||
builtInProp = function builtInProp(obj,name,val,config) {
|
|
||||||
return Object.defineProperty(obj,name,{
|
|
||||||
value: val,
|
|
||||||
writable: true,
|
|
||||||
configurable: config !== false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
builtInProp = function builtInProp(obj,name,val) {
|
|
||||||
obj[name] = val;
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: using a queue instead of array for efficiency
|
|
||||||
scheduling_queue = (function Queue() {
|
|
||||||
var first, last, item;
|
|
||||||
|
|
||||||
function Item(fn,self) {
|
|
||||||
this.fn = fn;
|
|
||||||
this.self = self;
|
|
||||||
this.next = void 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
add: function add(fn,self) {
|
|
||||||
item = new Item(fn,self);
|
|
||||||
if (last) {
|
|
||||||
last.next = item;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
first = item;
|
|
||||||
}
|
|
||||||
last = item;
|
|
||||||
item = void 0;
|
|
||||||
},
|
|
||||||
drain: function drain() {
|
|
||||||
var f = first;
|
|
||||||
first = last = cycle = void 0;
|
|
||||||
|
|
||||||
while (f) {
|
|
||||||
f.fn.call(f.self);
|
|
||||||
f = f.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
function schedule(fn,self) {
|
|
||||||
scheduling_queue.add(fn,self);
|
|
||||||
if (!cycle) {
|
|
||||||
cycle = timer(scheduling_queue.drain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// promise duck typing
|
|
||||||
function isThenable(o) {
|
|
||||||
var _then, o_type = typeof o;
|
|
||||||
|
|
||||||
if (o != null &&
|
|
||||||
(
|
|
||||||
o_type == "object" || o_type == "function"
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
_then = o.then;
|
|
||||||
}
|
|
||||||
return typeof _then == "function" ? _then : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function notify() {
|
|
||||||
for (var i=0; i<this.chain.length; i++) {
|
|
||||||
notifyIsolated(
|
|
||||||
this,
|
|
||||||
(this.state === 1) ? this.chain[i].success : this.chain[i].failure,
|
|
||||||
this.chain[i]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this.chain.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: This is a separate function to isolate
|
|
||||||
// the `try..catch` so that other code can be
|
|
||||||
// optimized better
|
|
||||||
function notifyIsolated(self,cb,chain) {
|
|
||||||
var ret, _then;
|
|
||||||
try {
|
|
||||||
if (cb === false) {
|
|
||||||
chain.reject(self.msg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (cb === true) {
|
|
||||||
ret = self.msg;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = cb.call(void 0,self.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret === chain.promise) {
|
|
||||||
chain.reject(TypeError("Promise-chain cycle"));
|
|
||||||
}
|
|
||||||
else if (_then = isThenable(ret)) {
|
|
||||||
_then.call(ret,chain.resolve,chain.reject);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
chain.resolve(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
chain.reject(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolve(msg) {
|
|
||||||
var _then, self = this;
|
|
||||||
|
|
||||||
// already triggered?
|
|
||||||
if (self.triggered) { return; }
|
|
||||||
|
|
||||||
self.triggered = true;
|
|
||||||
|
|
||||||
// unwrap
|
|
||||||
if (self.def) {
|
|
||||||
self = self.def;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (_then = isThenable(msg)) {
|
|
||||||
schedule(function(){
|
|
||||||
var def_wrapper = new MakeDefWrapper(self);
|
|
||||||
try {
|
|
||||||
_then.call(msg,
|
|
||||||
function $resolve$(){ resolve.apply(def_wrapper,arguments); },
|
|
||||||
function $reject$(){ reject.apply(def_wrapper,arguments); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject.call(def_wrapper,err);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.msg = msg;
|
|
||||||
self.state = 1;
|
|
||||||
if (self.chain.length > 0) {
|
|
||||||
schedule(notify,self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject.call(new MakeDefWrapper(self),err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function reject(msg) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// already triggered?
|
|
||||||
if (self.triggered) { return; }
|
|
||||||
|
|
||||||
self.triggered = true;
|
|
||||||
|
|
||||||
// unwrap
|
|
||||||
if (self.def) {
|
|
||||||
self = self.def;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.msg = msg;
|
|
||||||
self.state = 2;
|
|
||||||
if (self.chain.length > 0) {
|
|
||||||
schedule(notify,self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function iteratePromises(Constructor,arr,resolver,rejecter) {
|
|
||||||
for (var idx=0; idx<arr.length; idx++) {
|
|
||||||
(function IIFE(idx){
|
|
||||||
Constructor.resolve(arr[idx])
|
|
||||||
.then(
|
|
||||||
function $resolver$(msg){
|
|
||||||
resolver(idx,msg);
|
|
||||||
},
|
|
||||||
rejecter
|
|
||||||
);
|
|
||||||
})(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function MakeDefWrapper(self) {
|
|
||||||
this.def = self;
|
|
||||||
this.triggered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MakeDef(self) {
|
|
||||||
this.promise = self;
|
|
||||||
this.state = 0;
|
|
||||||
this.triggered = false;
|
|
||||||
this.chain = [];
|
|
||||||
this.msg = void 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Promise(executor) {
|
|
||||||
if (typeof executor != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.__NPO__ !== 0) {
|
|
||||||
throw TypeError("Not a promise");
|
|
||||||
}
|
|
||||||
|
|
||||||
// instance shadowing the inherited "brand"
|
|
||||||
// to signal an already "initialized" promise
|
|
||||||
this.__NPO__ = 1;
|
|
||||||
|
|
||||||
var def = new MakeDef(this);
|
|
||||||
|
|
||||||
this["then"] = function then(success,failure) {
|
|
||||||
var o = {
|
|
||||||
success: typeof success == "function" ? success : true,
|
|
||||||
failure: typeof failure == "function" ? failure : false
|
|
||||||
};
|
|
||||||
// Note: `then(..)` itself can be borrowed to be used against
|
|
||||||
// a different promise constructor for making the chained promise,
|
|
||||||
// by substituting a different `this` binding.
|
|
||||||
o.promise = new this.constructor(function extractChain(resolve,reject) {
|
|
||||||
if (typeof resolve != "function" || typeof reject != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
o.resolve = resolve;
|
|
||||||
o.reject = reject;
|
|
||||||
});
|
|
||||||
def.chain.push(o);
|
|
||||||
|
|
||||||
if (def.state !== 0) {
|
|
||||||
schedule(notify,def);
|
|
||||||
}
|
|
||||||
|
|
||||||
return o.promise;
|
|
||||||
};
|
|
||||||
this["catch"] = function $catch$(failure) {
|
|
||||||
return this.then(void 0,failure);
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
executor.call(
|
|
||||||
void 0,
|
|
||||||
function publicResolve(msg){
|
|
||||||
resolve.call(def,msg);
|
|
||||||
},
|
|
||||||
function publicReject(msg) {
|
|
||||||
reject.call(def,msg);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject.call(def,err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var PromisePrototype = builtInProp({},"constructor",Promise,
|
|
||||||
/*configurable=*/false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Note: Android 4 cannot use `Object.defineProperty(..)` here
|
|
||||||
Promise.prototype = PromisePrototype;
|
|
||||||
|
|
||||||
// built-in "brand" to signal an "uninitialized" promise
|
|
||||||
builtInProp(PromisePrototype,"__NPO__",0,
|
|
||||||
/*configurable=*/false
|
|
||||||
);
|
|
||||||
|
|
||||||
builtInProp(Promise,"resolve",function Promise$resolve(msg) {
|
|
||||||
var Constructor = this;
|
|
||||||
|
|
||||||
// spec mandated checks
|
|
||||||
// note: best "isPromise" check that's practical for now
|
|
||||||
if (msg && typeof msg == "object" && msg.__NPO__ === 1) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Constructor(function executor(resolve,reject){
|
|
||||||
if (typeof resolve != "function" || typeof reject != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(msg);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
builtInProp(Promise,"reject",function Promise$reject(msg) {
|
|
||||||
return new this(function executor(resolve,reject){
|
|
||||||
if (typeof resolve != "function" || typeof reject != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
reject(msg);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
builtInProp(Promise,"all",function Promise$all(arr) {
|
|
||||||
var Constructor = this;
|
|
||||||
|
|
||||||
// spec mandated checks
|
|
||||||
if (ToString.call(arr) != "[object Array]") {
|
|
||||||
return Constructor.reject(TypeError("Not an array"));
|
|
||||||
}
|
|
||||||
if (arr.length === 0) {
|
|
||||||
return Constructor.resolve([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Constructor(function executor(resolve,reject){
|
|
||||||
if (typeof resolve != "function" || typeof reject != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
var len = arr.length, msgs = Array(len), count = 0;
|
|
||||||
|
|
||||||
iteratePromises(Constructor,arr,function resolver(idx,msg) {
|
|
||||||
msgs[idx] = msg;
|
|
||||||
if (++count === len) {
|
|
||||||
resolve(msgs);
|
|
||||||
}
|
|
||||||
},reject);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
builtInProp(Promise,"race",function Promise$race(arr) {
|
|
||||||
var Constructor = this;
|
|
||||||
|
|
||||||
// spec mandated checks
|
|
||||||
if (ToString.call(arr) != "[object Array]") {
|
|
||||||
return Constructor.reject(TypeError("Not an array"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Constructor(function executor(resolve,reject){
|
|
||||||
if (typeof resolve != "function" || typeof reject != "function") {
|
|
||||||
throw TypeError("Not a function");
|
|
||||||
}
|
|
||||||
|
|
||||||
iteratePromises(Constructor,arr,function resolver(idx,msg){
|
|
||||||
resolve(msg);
|
|
||||||
},reject);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise;
|
|
||||||
});
|
|
35
external/qunit/LICENSE.txt
vendored
35
external/qunit/LICENSE.txt
vendored
@ -1,35 +0,0 @@
|
|||||||
Copyright JS Foundation and other contributors, https://js.foundation
|
|
||||||
|
|
||||||
This software consists of voluntary contributions made by many
|
|
||||||
individuals. For exact contribution history, see the revision history
|
|
||||||
available at https://github.com/qunitjs/qunit
|
|
||||||
|
|
||||||
The following license applies to all parts of this software except as
|
|
||||||
documented below:
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
All files located in the node_modules directory are externally maintained
|
|
||||||
libraries used by this software which have their own licenses; we
|
|
||||||
recommend you read them, as their terms may differ from the terms above.
|
|
436
external/qunit/qunit.css
vendored
436
external/qunit/qunit.css
vendored
@ -1,436 +0,0 @@
|
|||||||
/*!
|
|
||||||
* QUnit 2.9.2
|
|
||||||
* https://qunitjs.com/
|
|
||||||
*
|
|
||||||
* Copyright jQuery Foundation and other contributors
|
|
||||||
* Released under the MIT license
|
|
||||||
* https://jquery.org/license
|
|
||||||
*
|
|
||||||
* Date: 2019-02-21T22:49Z
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Font Family and Sizes */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult {
|
|
||||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
|
||||||
#qunit-tests { font-size: smaller; }
|
|
||||||
|
|
||||||
|
|
||||||
/** Resets */
|
|
||||||
|
|
||||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Header (excluding toolbar) */
|
|
||||||
|
|
||||||
#qunit-header {
|
|
||||||
padding: 0.5em 0 0.5em 1em;
|
|
||||||
|
|
||||||
color: #8699A4;
|
|
||||||
background-color: #0D3349;
|
|
||||||
|
|
||||||
font-size: 1.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
font-weight: 400;
|
|
||||||
|
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #C2CCD1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-header a:hover,
|
|
||||||
#qunit-header a:focus {
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-banner {
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-filteredTest {
|
|
||||||
padding: 0.5em 1em 0.5em 1em;
|
|
||||||
color: #366097;
|
|
||||||
background-color: #F4FF77;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-userAgent {
|
|
||||||
padding: 0.5em 1em 0.5em 1em;
|
|
||||||
color: #FFF;
|
|
||||||
background-color: #2B81AF;
|
|
||||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Toolbar */
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar {
|
|
||||||
padding: 0.5em 1em 0.5em 1em;
|
|
||||||
color: #5E740B;
|
|
||||||
background-color: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar .clearfix {
|
|
||||||
height: 0;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar label {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar input[type=checkbox],
|
|
||||||
#qunit-testrunner-toolbar input[type=radio] {
|
|
||||||
margin: 3px;
|
|
||||||
vertical-align: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-testrunner-toolbar input[type=text] {
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-url-config,
|
|
||||||
.qunit-filter,
|
|
||||||
#qunit-modulefilter {
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 2.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-filter,
|
|
||||||
#qunit-modulefilter {
|
|
||||||
float: right;
|
|
||||||
position: relative;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-url-config label {
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-search {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-search-container:after {
|
|
||||||
position: absolute;
|
|
||||||
right: 0.3em;
|
|
||||||
content: "\25bc";
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown {
|
|
||||||
/* align with #qunit-modulefilter-search */
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 400px;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: 0.8em;
|
|
||||||
|
|
||||||
border: 1px solid #D3D3D3;
|
|
||||||
border-top: none;
|
|
||||||
border-radius: 0 0 .25em .25em;
|
|
||||||
color: #000;
|
|
||||||
background-color: #F5F5F5;
|
|
||||||
z-index: 99;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown .clickable.checked {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000;
|
|
||||||
background-color: #D2E0E6;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown .clickable:hover {
|
|
||||||
color: #FFF;
|
|
||||||
background-color: #0D3349;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-actions {
|
|
||||||
display: block;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
/* align with #qunit-modulefilter-dropdown-list */
|
|
||||||
font: smaller/1.5em sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * {
|
|
||||||
box-sizing: border-box;
|
|
||||||
max-height: 2.8em;
|
|
||||||
display: block;
|
|
||||||
padding: 0.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button {
|
|
||||||
float: right;
|
|
||||||
font: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child {
|
|
||||||
/* insert padding to align with checkbox margins */
|
|
||||||
padding-left: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown-list {
|
|
||||||
max-height: 200px;
|
|
||||||
overflow-y: auto;
|
|
||||||
margin: 0;
|
|
||||||
border-top: 2px groove threedhighlight;
|
|
||||||
padding: 0.4em 0 0;
|
|
||||||
font: smaller/1.5em sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown-list li {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-modulefilter-dropdown-list .clickable {
|
|
||||||
display: block;
|
|
||||||
padding-left: 0.15em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tests: Pass/Fail */
|
|
||||||
|
|
||||||
#qunit-tests {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li {
|
|
||||||
padding: 0.4em 1em 0.4em 1em;
|
|
||||||
border-bottom: 1px solid #FFF;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests > li {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li.running,
|
|
||||||
#qunit-tests li.pass,
|
|
||||||
#qunit-tests li.fail,
|
|
||||||
#qunit-tests li.skipped,
|
|
||||||
#qunit-tests li.aborted {
|
|
||||||
display: list-item;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests.hidepass {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests.hidepass li.running,
|
|
||||||
#qunit-tests.hidepass li.pass:not(.todo) {
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li strong {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li.skipped strong {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li a {
|
|
||||||
padding: 0.5em;
|
|
||||||
color: #C2CCD1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li p a {
|
|
||||||
padding: 0.25em;
|
|
||||||
color: #6B6464;
|
|
||||||
}
|
|
||||||
#qunit-tests li a:hover,
|
|
||||||
#qunit-tests li a:focus {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests li .runtime {
|
|
||||||
float: right;
|
|
||||||
font-size: smaller;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-assert-list {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background-color: #FFF;
|
|
||||||
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-source {
|
|
||||||
margin: 0.6em 0 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qunit-collapsed {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-top: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests th {
|
|
||||||
text-align: right;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0 0.5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests td {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests pre {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests del {
|
|
||||||
color: #374E0C;
|
|
||||||
background-color: #E0F2BE;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests ins {
|
|
||||||
color: #500;
|
|
||||||
background-color: #FFCACA;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Test Counts */
|
|
||||||
|
|
||||||
#qunit-tests b.counts { color: #000; }
|
|
||||||
#qunit-tests b.passed { color: #5E740B; }
|
|
||||||
#qunit-tests b.failed { color: #710909; }
|
|
||||||
|
|
||||||
#qunit-tests li li {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #FFF;
|
|
||||||
border-bottom: none;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Passing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.pass {
|
|
||||||
color: #3C510C;
|
|
||||||
background-color: #FFF;
|
|
||||||
border-left: 10px solid #C6E746;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
|
||||||
#qunit-tests .pass .test-name { color: #366097; }
|
|
||||||
|
|
||||||
#qunit-tests .pass .test-actual,
|
|
||||||
#qunit-tests .pass .test-expected { color: #999; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
|
||||||
|
|
||||||
/*** Failing Styles */
|
|
||||||
|
|
||||||
#qunit-tests li li.fail {
|
|
||||||
color: #710909;
|
|
||||||
background-color: #FFF;
|
|
||||||
border-left: 10px solid #EE5757;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests > li:last-child {
|
|
||||||
border-radius: 0 0 5px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .fail { color: #000; background-color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-name,
|
|
||||||
#qunit-tests .fail .module-name { color: #000; }
|
|
||||||
|
|
||||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
|
||||||
#qunit-tests .fail .test-expected { color: #008000; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
|
||||||
|
|
||||||
|
|
||||||
/*** Aborted tests */
|
|
||||||
#qunit-tests .aborted { color: #000; background-color: orange; }
|
|
||||||
/*** Skipped tests */
|
|
||||||
|
|
||||||
#qunit-tests .skipped {
|
|
||||||
background-color: #EBECE9;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .qunit-todo-label,
|
|
||||||
#qunit-tests .qunit-skipped-label {
|
|
||||||
background-color: #F4FF77;
|
|
||||||
display: inline-block;
|
|
||||||
font-style: normal;
|
|
||||||
color: #366097;
|
|
||||||
line-height: 1.8em;
|
|
||||||
padding: 0 0.5em;
|
|
||||||
margin: -0.4em 0.4em -0.4em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#qunit-tests .qunit-todo-label {
|
|
||||||
background-color: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Result */
|
|
||||||
|
|
||||||
#qunit-testresult {
|
|
||||||
color: #2B81AF;
|
|
||||||
background-color: #D2E0E6;
|
|
||||||
|
|
||||||
border-bottom: 1px solid #FFF;
|
|
||||||
}
|
|
||||||
#qunit-testresult .clearfix {
|
|
||||||
height: 0;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
#qunit-testresult .module-name {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
#qunit-testresult-display {
|
|
||||||
padding: 0.5em 1em 0.5em 1em;
|
|
||||||
width: 85%;
|
|
||||||
float:left;
|
|
||||||
}
|
|
||||||
#qunit-testresult-controls {
|
|
||||||
padding: 0.5em 1em 0.5em 1em;
|
|
||||||
width: 10%;
|
|
||||||
float:left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fixture */
|
|
||||||
|
|
||||||
#qunit-fixture {
|
|
||||||
position: absolute;
|
|
||||||
top: -10000px;
|
|
||||||
left: -10000px;
|
|
||||||
width: 1000px;
|
|
||||||
height: 1000px;
|
|
||||||
}
|
|
6604
external/qunit/qunit.js
vendored
6604
external/qunit/qunit.js
vendored
File diff suppressed because it is too large
Load Diff
2145
external/requirejs/require.js
vendored
2145
external/requirejs/require.js
vendored
File diff suppressed because it is too large
Load Diff
27
external/sinon/LICENSE.txt
vendored
27
external/sinon/LICENSE.txt
vendored
@ -1,27 +0,0 @@
|
|||||||
(The BSD License)
|
|
||||||
|
|
||||||
Copyright (c) 2010-2017, Christian Johansen, christian@cjohansen.no
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Christian Johansen nor the names of his contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
11809
external/sinon/sinon.js
vendored
11809
external/sinon/sinon.js
vendored
File diff suppressed because one or more lines are too long
7533
package-lock.json
generated
Normal file
7533
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
77
package.json
77
package.json
@ -4,6 +4,31 @@
|
|||||||
"description": "JavaScript library for DOM operations",
|
"description": "JavaScript library for DOM operations",
|
||||||
"version": "3.7.2-pre",
|
"version": "3.7.2-pre",
|
||||||
"main": "dist/jquery.js",
|
"main": "dist/jquery.js",
|
||||||
|
"scripts": {
|
||||||
|
"babel:tests": "babel test/data/core/jquery-iterability-transpiled-es6.js --out-file test/data/core/jquery-iterability-transpiled.js",
|
||||||
|
"build": "node ./build/command.js",
|
||||||
|
"build:all": "node -e \"require('./build/tasks/build.js').buildDefaultFiles()\"",
|
||||||
|
"build:main": "node -e \"require('./build/tasks/build.js').build()\"",
|
||||||
|
"jenkins": "npm run pretest && npm run test:browserless",
|
||||||
|
"lint:dev": "eslint --cache .",
|
||||||
|
"lint:json": "jsonlint --quiet package.json",
|
||||||
|
"lint": "concurrently -r \"npm:lint:dev\" \"npm:lint:json\"",
|
||||||
|
"npmcopy": "node build/tasks/npmcopy.js",
|
||||||
|
"prepare": "husky install",
|
||||||
|
"pretest": "npm run qunit-fixture && npm run babel:tests && npm run npmcopy",
|
||||||
|
"qunit-fixture": "node build/tasks/qunit-fixture.js",
|
||||||
|
"start": "nodemon --watch src -x \"npm run build:all\"",
|
||||||
|
"test:browserless": "npm run test:node_smoke_tests && npm run test:promises_aplus && npm run test:jsdom",
|
||||||
|
"test:browser": "npm run build:all && grunt karma:main",
|
||||||
|
"test:amd": "npm run build:main && grunt karma:amd",
|
||||||
|
"test:jsdom": "npm run build:main && grunt test:jsdom",
|
||||||
|
"test:no-deprecated": "npm run build -- -e deprecated && grunt karma:main",
|
||||||
|
"test:selector-native": "npm run build -- -e selector && grunt karma:main",
|
||||||
|
"test:slim": "npm run build -- --slim && grunt karma:main",
|
||||||
|
"test:node_smoke_tests": "npm run build:all && node build/tasks/node_smoke_tests.js",
|
||||||
|
"test:promises_aplus": "npm run build:main && node build/tasks/promises_aplus_tests.js",
|
||||||
|
"test": "npm run build:all && npm run lint && npm run test:browserless && npm run test:browser && npm run test:amd && npm run test:slim && npm run test:no-deprecated && npm run test:selector-native"
|
||||||
|
},
|
||||||
"homepage": "https://jquery.com",
|
"homepage": "https://jquery.com",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "OpenJS Foundation and other contributors",
|
"name": "OpenJS Foundation and other contributors",
|
||||||
@ -24,27 +49,25 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.3.3",
|
"@babel/cli": "7.22.10",
|
||||||
"@babel/plugin-transform-for-of": "7.2.0",
|
"@babel/core": "7.22.11",
|
||||||
|
"@babel/plugin-transform-for-of": "7.22.5",
|
||||||
|
"@prantlf/jsonlint": "14.0.3",
|
||||||
"bootstrap": "5.3.0",
|
"bootstrap": "5.3.0",
|
||||||
|
"chalk": "5.3.0",
|
||||||
"colors": "1.4.0",
|
"colors": "1.4.0",
|
||||||
"commitplease": "3.2.0",
|
"commitplease": "3.2.0",
|
||||||
"core-js": "2.6.5",
|
"concurrently": "8.2.0",
|
||||||
"eslint-config-jquery": "3.0.0",
|
"core-js-bundle": "3.32.1",
|
||||||
|
"eslint": "8.48.0",
|
||||||
|
"eslint-config-jquery": "3.0.1",
|
||||||
|
"express": "4.18.2",
|
||||||
|
"globals": "13.20.0",
|
||||||
"grunt": "1.5.3",
|
"grunt": "1.5.3",
|
||||||
"grunt-babel": "8.0.0",
|
|
||||||
"grunt-cli": "1.4.3",
|
"grunt-cli": "1.4.3",
|
||||||
"grunt-compare-size": "0.4.2",
|
|
||||||
"grunt-contrib-uglify": "3.4.0",
|
|
||||||
"grunt-contrib-watch": "1.1.0",
|
|
||||||
"grunt-eslint": "22.0.0",
|
|
||||||
"grunt-git-authors": "3.2.0",
|
"grunt-git-authors": "3.2.0",
|
||||||
"grunt-jsonlint": "2.1.2",
|
|
||||||
"grunt-karma": "4.0.2",
|
"grunt-karma": "4.0.2",
|
||||||
"grunt-newer": "1.3.0",
|
"husky": "8.0.3",
|
||||||
"grunt-npmcopy": "0.2.0",
|
|
||||||
"gzip-js": "0.3.2",
|
|
||||||
"husky": "4.2.5",
|
|
||||||
"jsdom": "19.0.0",
|
"jsdom": "19.0.0",
|
||||||
"karma": "6.4.1",
|
"karma": "6.4.1",
|
||||||
"karma-browserstack-launcher": "1.6.0",
|
"karma-browserstack-launcher": "1.6.0",
|
||||||
@ -56,6 +79,7 @@
|
|||||||
"karma-webkit-launcher": "2.1.0",
|
"karma-webkit-launcher": "2.1.0",
|
||||||
"load-grunt-tasks": "5.1.0",
|
"load-grunt-tasks": "5.1.0",
|
||||||
"native-promise-only": "0.8.1",
|
"native-promise-only": "0.8.1",
|
||||||
|
"nodemon": "3.0.1",
|
||||||
"playwright-webkit": "1.30.0",
|
"playwright-webkit": "1.30.0",
|
||||||
"promises-aplus-tests": "2.1.2",
|
"promises-aplus-tests": "2.1.2",
|
||||||
"q": "1.5.1",
|
"q": "1.5.1",
|
||||||
@ -65,23 +89,8 @@
|
|||||||
"sinon": "2.3.7",
|
"sinon": "2.3.7",
|
||||||
"strip-json-comments": "2.0.1",
|
"strip-json-comments": "2.0.1",
|
||||||
"testswarm": "1.1.2",
|
"testswarm": "1.1.2",
|
||||||
"uglify-js": "3.4.7"
|
"uglify-js": "3.4.7",
|
||||||
},
|
"yargs": "17.7.2"
|
||||||
"scripts": {
|
|
||||||
"build": "npm install && npm run build-all-variants",
|
|
||||||
"build-all-variants": "grunt custom:slim --filename=jquery.slim.js && grunt custom",
|
|
||||||
"start": "grunt watch",
|
|
||||||
"test:browserless": "grunt && npm run test:node_smoke_tests && grunt test:slow",
|
|
||||||
"test:browser": "grunt && grunt karma:main",
|
|
||||||
"test:amd": "grunt && grunt karma:amd",
|
|
||||||
"test:no-deprecated": "grunt test:prepare && grunt custom:-deprecated && grunt karma:main",
|
|
||||||
"test:selector-native": "grunt test:prepare && grunt custom:-selector && grunt karma:main",
|
|
||||||
"test:slim": "grunt test:prepare && grunt custom:slim && grunt karma:main",
|
|
||||||
"test:node_smoke_tests:full": "grunt node_smoke_tests:./dist/jquery.js",
|
|
||||||
"test:node_smoke_tests:slim": "grunt node_smoke_tests:./dist/jquery.slim.js",
|
|
||||||
"test:node_smoke_tests": "npm run test:node_smoke_tests:full && npm run test:node_smoke_tests:slim",
|
|
||||||
"test": "npm run test:browserless && npm run test:slim && npm run test:no-deprecated && npm run test:selector-native && grunt && grunt test:slow && grunt karma:main && grunt karma:amd",
|
|
||||||
"jenkins": "npm run test:browserless"
|
|
||||||
},
|
},
|
||||||
"commitplease": {
|
"commitplease": {
|
||||||
"nohook": true,
|
"nohook": true,
|
||||||
@ -112,11 +121,5 @@
|
|||||||
],
|
],
|
||||||
"markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|^(refs?)",
|
"markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|^(refs?)",
|
||||||
"ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|^(Refs? [^#])"
|
"ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|^(Refs? [^#])"
|
||||||
},
|
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"commit-msg": "commitplease .git/COMMIT_EDITMSG",
|
|
||||||
"pre-commit": "grunt lint:newer qunit_fixture"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "../.eslintrc-browser.json",
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
"indent": [ "error", "tab", {
|
|
||||||
"outerIIFEBody": 0,
|
|
||||||
|
|
||||||
// Ignore the top level function defining an AMD module
|
|
||||||
"ignoredNodes": [
|
|
||||||
"Program > ExpressionStatement > CallExpression > :last-child > *"
|
|
||||||
]
|
|
||||||
} ]
|
|
||||||
},
|
|
||||||
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "wrapper.js",
|
|
||||||
"rules": {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"indent": [ "error", "tab", {
|
|
||||||
|
|
||||||
// Unlike other codes, "wrapper.js" is implemented in UMD.
|
|
||||||
// So it required a specific exception for jQuery's UMD
|
|
||||||
// Code Style. This makes that indentation check is not
|
|
||||||
// performed for 1 depth of outer FunctionExpressions
|
|
||||||
"ignoredNodes": [
|
|
||||||
"Program > ExpressionStatement > CallExpression > :last-child > *"
|
|
||||||
]
|
|
||||||
} ]
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"jQuery": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"files": "selector.js",
|
|
||||||
"rules": {
|
|
||||||
"indent": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "../.eslintrc-browser.json",
|
|
||||||
|
|
||||||
"env": {
|
|
||||||
|
|
||||||
// In source the browser env is not enabled but unit tests rely on them
|
|
||||||
// too much and we don't run them in non-browser environments anyway.
|
|
||||||
"browser": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"globals": {
|
|
||||||
"require": false,
|
|
||||||
"Promise": false,
|
|
||||||
"Symbol": false,
|
|
||||||
"QUnit": false,
|
|
||||||
"ajaxTest": false,
|
|
||||||
"testIframe": false,
|
|
||||||
"createDashboardXML": false,
|
|
||||||
"createWithFriesXML": false,
|
|
||||||
"createXMLFragment": false,
|
|
||||||
"includesModule": false,
|
|
||||||
"moduleTeardown": false,
|
|
||||||
"url": false,
|
|
||||||
"q": false,
|
|
||||||
"jQuery": true,
|
|
||||||
"sinon": true,
|
|
||||||
"amdDefined": true,
|
|
||||||
"fireNative": true,
|
|
||||||
"Globals": true,
|
|
||||||
"hasPHP": true,
|
|
||||||
"isLocal": true,
|
|
||||||
"supportjQuery": true,
|
|
||||||
"originaljQuery": true,
|
|
||||||
"$": true,
|
|
||||||
"original$": true,
|
|
||||||
"baseURL": true,
|
|
||||||
"externalHost": true
|
|
||||||
},
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
// See https://github.com/eslint/eslint/issues/2342
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
|
|
||||||
// Too many errors
|
|
||||||
"max-len": "off",
|
|
||||||
"brace-style": "off",
|
|
||||||
"key-spacing": "off",
|
|
||||||
"camelcase": "off",
|
|
||||||
"one-var": "off",
|
|
||||||
"strict": "off",
|
|
||||||
|
|
||||||
// Not really too many - waiting for autofix features for these rules
|
|
||||||
"lines-around-comment": "off",
|
|
||||||
"dot-notation": "off"
|
|
||||||
},
|
|
||||||
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": [
|
|
||||||
"middleware-mockserver.js"
|
|
||||||
],
|
|
||||||
|
|
||||||
"extends": "../.eslintrc-node.json"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"files": [
|
|
||||||
"data/core/jquery-iterability-transpiled-es6.js",
|
|
||||||
"data/testinit-jsdom.js"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2015
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
5
test/data/core/.babelrc.json
Normal file
5
test/data/core/.babelrc.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["@babel/transform-for-of"],
|
||||||
|
"retainLines": true,
|
||||||
|
"sourceMaps": "inline"
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<title>jQuery objects transpiled iterability test page</title>
|
<title>jQuery objects transpiled iterability test page</title>
|
||||||
<script src="../../../external/core-js/core-js.js"></script>
|
<script src="../../../external/core-js-bundle/core-js-bundle.js"></script>
|
||||||
<script src="../../jquery.js"></script>
|
<script src="../../jquery.js"></script>
|
||||||
<script src="../iframeTest.js"></script>
|
<script src="../iframeTest.js"></script>
|
||||||
<script src="jquery-iterability-transpiled.js"></script>
|
<script src="jquery-iterability-transpiled.js"></script>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="../../../external/bootstrap/bootstrap.min.css" class="stylesheet">
|
<link rel="stylesheet" href="../../../external/bootstrap/bootstrap.min.css" class="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
@ -34,10 +34,10 @@ window.original$ = this.$ = "replaced";
|
|||||||
* @example url("mock.php?foo=bar")
|
* @example url("mock.php?foo=bar")
|
||||||
* @result "data/mock.php?foo=bar&10538358345554"
|
* @result "data/mock.php?foo=bar&10538358345554"
|
||||||
*/
|
*/
|
||||||
function url( value ) {
|
this.url = function( value ) {
|
||||||
return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) +
|
return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) +
|
||||||
new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 );
|
new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 );
|
||||||
}
|
};
|
||||||
|
|
||||||
// We only run basic tests in jsdom so we don't need to repeat the logic
|
// We only run basic tests in jsdom so we don't need to repeat the logic
|
||||||
// from the regular testinit.js
|
// from the regular testinit.js
|
||||||
|
@ -17,13 +17,7 @@ var FILEPATH = "/test/data/testinit.js",
|
|||||||
supportjQuery = this.jQuery,
|
supportjQuery = this.jQuery,
|
||||||
|
|
||||||
// see RFC 2606
|
// see RFC 2606
|
||||||
externalHost = "example.com",
|
externalHost = "example.com";
|
||||||
|
|
||||||
// NOTE: keep it in sync with build/tasks/lib/slim-build-flags.js
|
|
||||||
slimBuildFlags = [
|
|
||||||
"-ajax",
|
|
||||||
"-effects"
|
|
||||||
];
|
|
||||||
|
|
||||||
this.hasPHP = true;
|
this.hasPHP = true;
|
||||||
this.isLocal = window.location.protocol === "file:";
|
this.isLocal = window.location.protocol === "file:";
|
||||||
@ -265,7 +259,7 @@ this.ajaxTest = function( title, expect, options ) {
|
|||||||
completed = true;
|
completed = true;
|
||||||
delete ajaxTest.abort;
|
delete ajaxTest.abort;
|
||||||
assert.ok( false, "aborted " + reason );
|
assert.ok( false, "aborted " + reason );
|
||||||
jQuery.each( requests, function( i, request ) {
|
jQuery.each( requests, function( _i, request ) {
|
||||||
request.abort();
|
request.abort();
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@ -346,16 +340,8 @@ this.includesModule = function( moduleName ) {
|
|||||||
|
|
||||||
var excludedModulesPart, excludedModules;
|
var excludedModulesPart, excludedModules;
|
||||||
|
|
||||||
// A short-cut for the slim build, e.g. "4.0.0-pre slim"
|
// example version for `npm run build -- -e deprecated`:
|
||||||
if ( jQuery.fn.jquery.indexOf( " slim" ) > -1 ) {
|
// "v3.7.2-pre+14dc9347 -deprecated,-deprecated/ajax-event-alias,-deprecated/event"
|
||||||
|
|
||||||
// The module is included if it does NOT exist on the list
|
|
||||||
// of modules excluded in the slim build
|
|
||||||
return slimBuildFlags.indexOf( "-" + moduleName ) === -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// example version for `grunt custom:-deprecated`:
|
|
||||||
// "4.0.0-pre -deprecated,-deprecated/ajax-event-alias,-deprecated/event"
|
|
||||||
excludedModulesPart = jQuery.fn.jquery
|
excludedModulesPart = jQuery.fn.jquery
|
||||||
|
|
||||||
// Take the flags out of the version string.
|
// Take the flags out of the version string.
|
||||||
@ -420,6 +406,7 @@ this.loadTests = function() {
|
|||||||
|
|
||||||
var i = 0,
|
var i = 0,
|
||||||
tests = [
|
tests = [
|
||||||
|
|
||||||
// A special module with basic tests, meant for
|
// A special module with basic tests, meant for
|
||||||
// not fully supported environments like Android 2.3,
|
// not fully supported environments like Android 2.3,
|
||||||
// jsdom or PhantomJS. We run it everywhere, though,
|
// jsdom or PhantomJS. We run it everywhere, though,
|
||||||
|
@ -66,14 +66,34 @@ const mocks = {
|
|||||||
resp.end( "<root><element /></root>" );
|
resp.end( "<root><element /></root>" );
|
||||||
},
|
},
|
||||||
script: function( req, resp ) {
|
script: function( req, resp ) {
|
||||||
|
const headers = {};
|
||||||
if ( req.query.header === "ecma" ) {
|
if ( req.query.header === "ecma" ) {
|
||||||
resp.writeHead( 200, { "content-type": "application/ecmascript" } );
|
headers[ "content-type" ] = "application/ecmascript";
|
||||||
} else if ( "header" in req.query ) {
|
} else if ( "header" in req.query ) {
|
||||||
resp.writeHead( 200, { "content-type": "text/javascript" } );
|
headers[ "content-type" ] = "text/javascript";
|
||||||
} else {
|
} else {
|
||||||
resp.writeHead( 200, { "content-type": "text/html" } );
|
headers[ "content-type" ] = "text/html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( req.query.cors ) {
|
||||||
|
headers[ "access-control-allow-origin" ] = "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( resp.set ) {
|
||||||
|
resp.set( headers );
|
||||||
|
} else {
|
||||||
|
for ( const key in headers ) {
|
||||||
|
resp.writeHead( 200, { [ key ]: headers[ key ] } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( req.query.callback ) {
|
||||||
|
resp.end( `${ cleanCallback( req.query.callback ) }(${ JSON.stringify( {
|
||||||
|
headers: req.headers
|
||||||
|
} ) })` );
|
||||||
|
} else {
|
||||||
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
|
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
|
||||||
|
}
|
||||||
},
|
},
|
||||||
testbar: function( _req, resp ) {
|
testbar: function( _req, resp ) {
|
||||||
resp.writeHead( 200 );
|
resp.writeHead( 200 );
|
||||||
@ -137,14 +157,25 @@ const mocks = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
headers: function( req, resp ) {
|
headers: function( req, resp ) {
|
||||||
resp.writeHead( 200, {
|
const headers = {
|
||||||
"Sample-Header": "Hello World",
|
"Sample-Header": "Hello World",
|
||||||
"Empty-Header": "",
|
"Empty-Header": "",
|
||||||
"Sample-Header2": "Hello World 2",
|
"Sample-Header2": "Hello World 2",
|
||||||
"List-Header": "Item 1",
|
"List-Header": "Item 1",
|
||||||
"list-header": "Item 2",
|
"list-header": "Item 2",
|
||||||
"constructor": "prototype collision (constructor)"
|
"constructor": "prototype collision (constructor)"
|
||||||
} );
|
};
|
||||||
|
|
||||||
|
// Use resp.append in express to
|
||||||
|
// avoid overwriting List-Header
|
||||||
|
if ( resp.append ) {
|
||||||
|
|
||||||
|
for ( const key in headers ) {
|
||||||
|
resp.append( key, headers[ key ] );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp.writeHead( 200, headers );
|
||||||
|
}
|
||||||
req.query.keys.split( "|" ).forEach( function( key ) {
|
req.query.keys.split( "|" ).forEach( function( key ) {
|
||||||
if ( key.toLowerCase() in req.headers ) {
|
if ( key.toLowerCase() in req.headers ) {
|
||||||
resp.write( `${ key }: ${ req.headers[ key.toLowerCase() ] }\n` );
|
resp.write( `${ key }: ${ req.headers[ key.toLowerCase() ] }\n` );
|
||||||
@ -297,7 +328,7 @@ function MockserverMiddlewareFactory() {
|
|||||||
parsed: parsed
|
parsed: parsed
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( /^test\/data\/mock.php\//.test( path ) ) {
|
if ( /^\/?test\/data\/mock.php\/?/.test( path ) ) {
|
||||||
|
|
||||||
// Support REST-like Apache PathInfo
|
// Support REST-like Apache PathInfo
|
||||||
path = "test\/data\/mock.php";
|
path = "test\/data\/mock.php";
|
||||||
@ -308,6 +339,7 @@ function MockserverMiddlewareFactory() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log( "Mock handling", req.method, parsed.href );
|
||||||
handlers[ path ]( subReq, resp, next );
|
handlers[ path ]( subReq, resp, next );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "../../.eslintrc-node.json",
|
|
||||||
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2015,
|
|
||||||
"sourceType": "script"
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"es2020": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"root": true,
|
|
||||||
|
|
||||||
"extends": "../../.eslintrc-node.json"
|
|
||||||
}
|
|
21
test/server.js
Normal file
21
test/server.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const express = require( "express" );
|
||||||
|
const mockServer = require( "./middleware-mockserver" );
|
||||||
|
const fs = require( "fs" );
|
||||||
|
|
||||||
|
const nameHTML = fs.readFileSync( "./test/data/name.html", "utf8" );
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
app.use( mockServer() );
|
||||||
|
|
||||||
|
app.post( "/test/data/name.html", function( _req, res ) {
|
||||||
|
res.send( nameHTML );
|
||||||
|
} );
|
||||||
|
|
||||||
|
app.use( "/dist", express.static( "dist" ) );
|
||||||
|
app.use( "/src", express.static( "src" ) );
|
||||||
|
app.use( "/test", express.static( "test" ) );
|
||||||
|
app.use( "/external", express.static( "external" ) );
|
||||||
|
|
||||||
|
app.listen( 3000, function() {
|
||||||
|
console.log( "Server is running on port 3000" );
|
||||||
|
} );
|
@ -298,6 +298,7 @@ QUnit.module( "ajax", {
|
|||||||
assert.strictEqual( xhr.getResponseHeader( "Sample-Header2" ), "Hello World 2", "Second sample header received" );
|
assert.strictEqual( xhr.getResponseHeader( "Sample-Header2" ), "Hello World 2", "Second sample header received" );
|
||||||
|
|
||||||
if ( isAndroid ) {
|
if ( isAndroid ) {
|
||||||
|
|
||||||
// Support: Android 4.0-4.3 only
|
// Support: Android 4.0-4.3 only
|
||||||
// Android Browser only returns the last value for each header
|
// Android Browser only returns the last value for each header
|
||||||
// so there's no way for jQuery get all parts.
|
// so there's no way for jQuery get all parts.
|
||||||
@ -307,6 +308,7 @@ QUnit.module( "ajax", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( isAndroid && QUnit.isSwarm ) {
|
if ( isAndroid && QUnit.isSwarm ) {
|
||||||
|
|
||||||
// Support: Android 4.0-4.3 on BrowserStack only
|
// Support: Android 4.0-4.3 on BrowserStack only
|
||||||
// Android Browser versions provided by BrowserStack fail this test
|
// Android Browser versions provided by BrowserStack fail this test
|
||||||
// while locally fired emulators don't, even when they connect
|
// while locally fired emulators don't, even when they connect
|
||||||
@ -426,6 +428,7 @@ QUnit.module( "ajax", {
|
|||||||
},
|
},
|
||||||
cache: false,
|
cache: false,
|
||||||
beforeSend: function( xhr, settings ) {
|
beforeSend: function( xhr, settings ) {
|
||||||
|
|
||||||
// Clear the cache-buster param value
|
// Clear the cache-buster param value
|
||||||
var url = settings.url.replace( /_=[^&#]+/, "_=" );
|
var url = settings.url.replace( /_=[^&#]+/, "_=" );
|
||||||
assert.equal( url, baseURL + "name.html?abc&devo=hat&_=#brownies",
|
assert.equal( url, baseURL + "name.html?abc&devo=hat&_=#brownies",
|
||||||
@ -850,8 +853,8 @@ QUnit.module( "ajax", {
|
|||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data.match( /^html text/ ), "Check content for datatype html" );
|
assert.ok( data.match( /^html text/ ), "Check content for datatype html" );
|
||||||
jQuery( "#ap" ).html( data );
|
jQuery( "#ap" ).html( data );
|
||||||
assert.strictEqual( window[ "testFoo" ], "foo", "Check if script was evaluated for datatype html" );
|
assert.strictEqual( window.testFoo, "foo", "Check if script was evaluated for datatype html" );
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Check if script src was evaluated for datatype html" );
|
assert.strictEqual( window.testBar, "bar", "Check if script src was evaluated for datatype html" );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
@ -861,6 +864,7 @@ QUnit.module( "ajax", {
|
|||||||
return {
|
return {
|
||||||
dataType: "jsonp",
|
dataType: "jsonp",
|
||||||
url: url( "mock.php?action=errorWithScript" ),
|
url: url( "mock.php?action=errorWithScript" ),
|
||||||
|
|
||||||
// error is the significant assertion
|
// error is the significant assertion
|
||||||
error: function( xhr ) {
|
error: function( xhr ) {
|
||||||
var expected = { "status": 404, "msg": "Not Found" };
|
var expected = { "status": 404, "msg": "Not Found" };
|
||||||
@ -889,6 +893,7 @@ QUnit.module( "ajax", {
|
|||||||
complete: function() {
|
complete: function() {
|
||||||
jQuery.globalEval = globalEval;
|
jQuery.globalEval = globalEval;
|
||||||
},
|
},
|
||||||
|
|
||||||
// error is the significant assertion
|
// error is the significant assertion
|
||||||
error: function( xhr ) {
|
error: function( xhr ) {
|
||||||
assert.strictEqual( xhr.status, 404, testMsg );
|
assert.strictEqual( xhr.status, 404, testMsg );
|
||||||
@ -1148,8 +1153,8 @@ QUnit.module( "ajax", {
|
|||||||
Globals.register( "functionToCleanUp" );
|
Globals.register( "functionToCleanUp" );
|
||||||
Globals.register( "XXX" );
|
Globals.register( "XXX" );
|
||||||
Globals.register( "jsonpResults" );
|
Globals.register( "jsonpResults" );
|
||||||
window[ "jsonpResults" ] = function( data ) {
|
window.jsonpResults = function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (GET, custom callback function)" );
|
assert.ok( data.data, "JSON results returned (GET, custom callback function)" );
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
requests: [ {
|
requests: [ {
|
||||||
@ -1158,7 +1163,7 @@ QUnit.module( "ajax", {
|
|||||||
crossDomain: crossDomain,
|
crossDomain: crossDomain,
|
||||||
jsonp: "callback",
|
jsonp: "callback",
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (GET, data obj callback)" );
|
assert.ok( data.data, "JSON results returned (GET, data obj callback)" );
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
url: baseURL + "mock.php?action=jsonp",
|
url: baseURL + "mock.php?action=jsonp",
|
||||||
@ -1167,7 +1172,7 @@ QUnit.module( "ajax", {
|
|||||||
jsonpCallback: "jsonpResults",
|
jsonpCallback: "jsonpResults",
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
typeof window[ "jsonpResults" ],
|
typeof window.jsonpResults,
|
||||||
"function",
|
"function",
|
||||||
"should not rewrite original function"
|
"should not rewrite original function"
|
||||||
);
|
);
|
||||||
@ -1179,8 +1184,8 @@ QUnit.module( "ajax", {
|
|||||||
crossDomain: crossDomain,
|
crossDomain: crossDomain,
|
||||||
jsonpCallback: "functionToCleanUp",
|
jsonpCallback: "functionToCleanUp",
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (GET, custom callback name to be cleaned up)" );
|
assert.ok( data.data, "JSON results returned (GET, custom callback name to be cleaned up)" );
|
||||||
assert.strictEqual( window[ "functionToCleanUp" ], true, "Callback was removed (GET, custom callback name to be cleaned up)" );
|
assert.strictEqual( window.functionToCleanUp, true, "Callback was removed (GET, custom callback name to be cleaned up)" );
|
||||||
var xhr;
|
var xhr;
|
||||||
jQuery.ajax( {
|
jQuery.ajax( {
|
||||||
url: baseURL + "mock.php?action=jsonp",
|
url: baseURL + "mock.php?action=jsonp",
|
||||||
@ -1194,7 +1199,7 @@ QUnit.module( "ajax", {
|
|||||||
} );
|
} );
|
||||||
xhr.fail( function() {
|
xhr.fail( function() {
|
||||||
assert.ok( true, "Ajax error JSON (GET, custom callback name to be cleaned up)" );
|
assert.ok( true, "Ajax error JSON (GET, custom callback name to be cleaned up)" );
|
||||||
assert.strictEqual( window[ "functionToCleanUp" ], true, "Callback was removed after early abort (GET, custom callback name to be cleaned up)" );
|
assert.strictEqual( window.functionToCleanUp, true, "Callback was removed after early abort (GET, custom callback name to be cleaned up)" );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@ -1207,7 +1212,7 @@ QUnit.module( "ajax", {
|
|||||||
assert.ok( /action=jsonp&callback=XXX&_=\d+$/.test( this.url ), "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
|
assert.ok( /action=jsonp&callback=XXX&_=\d+$/.test( this.url ), "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
|
||||||
},
|
},
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (GET, custom callback name with no url manipulation)" );
|
assert.ok( data.data, "JSON results returned (GET, custom callback name with no url manipulation)" );
|
||||||
}
|
}
|
||||||
} ]
|
} ]
|
||||||
};
|
};
|
||||||
@ -1244,7 +1249,7 @@ QUnit.module( "ajax", {
|
|||||||
dataType: "jsonp",
|
dataType: "jsonp",
|
||||||
crossDomain: crossDomain,
|
crossDomain: crossDomain,
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (POST, no callback)" );
|
assert.ok( data.data, "JSON results returned (POST, no callback)" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1254,7 +1259,7 @@ QUnit.module( "ajax", {
|
|||||||
dataType: "jsonp",
|
dataType: "jsonp",
|
||||||
crossDomain: crossDomain,
|
crossDomain: crossDomain,
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (POST, data callback)" );
|
assert.ok( data.data, "JSON results returned (POST, data callback)" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1264,7 +1269,7 @@ QUnit.module( "ajax", {
|
|||||||
dataType: "jsonp",
|
dataType: "jsonp",
|
||||||
crossDomain: crossDomain,
|
crossDomain: crossDomain,
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
assert.ok( data[ "data" ], "JSON results returned (POST, data obj callback)" );
|
assert.ok( data.data, "JSON results returned (POST, data obj callback)" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -1312,7 +1317,7 @@ QUnit.module( "ajax", {
|
|||||||
url: url( "mock.php?action=testbar" ),
|
url: url( "mock.php?action=testbar" ),
|
||||||
dataType: "script",
|
dataType: "script",
|
||||||
success: function() {
|
success: function() {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Script results returned (GET, no callback)" );
|
assert.strictEqual( window.testBar, "bar", "Script results returned (GET, no callback)" );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
@ -1326,7 +1331,7 @@ QUnit.module( "ajax", {
|
|||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "script",
|
dataType: "script",
|
||||||
success: function( data, status ) {
|
success: function( data, status ) {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Script results returned (POST, no callback)" );
|
assert.strictEqual( window.testBar, "bar", "Script results returned (POST, no callback)" );
|
||||||
assert.strictEqual( status, "success", "Script results returned (POST, no callback)" );
|
assert.strictEqual( status, "success", "Script results returned (POST, no callback)" );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1340,7 +1345,7 @@ QUnit.module( "ajax", {
|
|||||||
url: url( "mock.php?action=testbar" ),
|
url: url( "mock.php?action=testbar" ),
|
||||||
dataType: "script",
|
dataType: "script",
|
||||||
success: function() {
|
success: function() {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Script results returned (GET, no callback)" );
|
assert.strictEqual( window.testBar, "bar", "Script results returned (GET, no callback)" );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
@ -1385,10 +1390,10 @@ QUnit.module( "ajax", {
|
|||||||
},
|
},
|
||||||
success: function( json ) {
|
success: function( json ) {
|
||||||
assert.ok( json.length >= 2, "Check length" );
|
assert.ok( json.length >= 2, "Check length" );
|
||||||
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
|
assert.strictEqual( json[ 0 ].name, "John", "Check JSON: first, name" );
|
||||||
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
|
assert.strictEqual( json[ 0 ].age, 21, "Check JSON: first, age" );
|
||||||
assert.strictEqual( json[ 1 ][ "name" ], "Peter", "Check JSON: second, name" );
|
assert.strictEqual( json[ 1 ].name, "Peter", "Check JSON: second, name" );
|
||||||
assert.strictEqual( json[ 1 ][ "age" ], 25, "Check JSON: second, age" );
|
assert.strictEqual( json[ 1 ].age, 25, "Check JSON: second, age" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1405,10 +1410,10 @@ QUnit.module( "ajax", {
|
|||||||
],
|
],
|
||||||
success: function( json ) {
|
success: function( json ) {
|
||||||
assert.ok( json.length >= 2, "Check length" );
|
assert.ok( json.length >= 2, "Check length" );
|
||||||
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
|
assert.strictEqual( json[ 0 ].name, "John", "Check JSON: first, name" );
|
||||||
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
|
assert.strictEqual( json[ 0 ].age, 21, "Check JSON: first, age" );
|
||||||
assert.strictEqual( json[ 1 ][ "name" ], "Peter", "Check JSON: second, name" );
|
assert.strictEqual( json[ 1 ].name, "Peter", "Check JSON: second, name" );
|
||||||
assert.strictEqual( json[ 1 ][ "age" ], 25, "Check JSON: second, age" );
|
assert.strictEqual( json[ 1 ].age, 25, "Check JSON: second, age" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -1429,10 +1434,10 @@ QUnit.module( "ajax", {
|
|||||||
assert.strictEqual( typeof text, "string", "json wasn't auto-determined" );
|
assert.strictEqual( typeof text, "string", "json wasn't auto-determined" );
|
||||||
var json = JSON.parse( text );
|
var json = JSON.parse( text );
|
||||||
assert.ok( json.length >= 2, "Check length" );
|
assert.ok( json.length >= 2, "Check length" );
|
||||||
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
|
assert.strictEqual( json[ 0 ].name, "John", "Check JSON: first, name" );
|
||||||
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
|
assert.strictEqual( json[ 0 ].age, 21, "Check JSON: first, age" );
|
||||||
assert.strictEqual( json[ 1 ][ "name" ], "Peter", "Check JSON: second, name" );
|
assert.strictEqual( json[ 1 ].name, "Peter", "Check JSON: second, name" );
|
||||||
assert.strictEqual( json[ 1 ][ "age" ], 25, "Check JSON: second, age" );
|
assert.strictEqual( json[ 1 ].age, 25, "Check JSON: second, age" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1454,10 +1459,10 @@ QUnit.module( "ajax", {
|
|||||||
assert.strictEqual( typeof text, "string", "json wasn't auto-determined" );
|
assert.strictEqual( typeof text, "string", "json wasn't auto-determined" );
|
||||||
var json = JSON.parse( text );
|
var json = JSON.parse( text );
|
||||||
assert.ok( json.length >= 2, "Check length" );
|
assert.ok( json.length >= 2, "Check length" );
|
||||||
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
|
assert.strictEqual( json[ 0 ].name, "John", "Check JSON: first, name" );
|
||||||
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
|
assert.strictEqual( json[ 0 ].age, 21, "Check JSON: first, age" );
|
||||||
assert.strictEqual( json[ 1 ][ "name" ], "Peter", "Check JSON: second, name" );
|
assert.strictEqual( json[ 1 ].name, "Peter", "Check JSON: second, name" );
|
||||||
assert.strictEqual( json[ 1 ][ "age" ], 25, "Check JSON: second, age" );
|
assert.strictEqual( json[ 1 ].age, 25, "Check JSON: second, age" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -1683,6 +1688,7 @@ QUnit.module( "ajax", {
|
|||||||
var ifModifiedNow = new Date();
|
var ifModifiedNow = new Date();
|
||||||
|
|
||||||
jQuery.each(
|
jQuery.each(
|
||||||
|
|
||||||
/* jQuery.each arguments start */
|
/* jQuery.each arguments start */
|
||||||
{
|
{
|
||||||
" (cache)": true,
|
" (cache)": true,
|
||||||
@ -1737,6 +1743,7 @@ QUnit.module( "ajax", {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jQuery.each arguments end */
|
/* jQuery.each arguments end */
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1813,6 +1820,7 @@ QUnit.module( "ajax", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jQuery.each(
|
jQuery.each(
|
||||||
|
|
||||||
/* jQuery.each arguments start */
|
/* jQuery.each arguments start */
|
||||||
{
|
{
|
||||||
"name.html": true,
|
"name.html": true,
|
||||||
@ -1887,6 +1895,7 @@ QUnit.module( "ajax", {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jQuery.each arguments end*/
|
/* jQuery.each arguments end*/
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
@ -2670,10 +2679,10 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
},
|
},
|
||||||
function( json ) {
|
function( json ) {
|
||||||
assert.ok( json.length >= 2, "Check length" );
|
assert.ok( json.length >= 2, "Check length" );
|
||||||
assert.strictEqual( json[ 0 ][ "name" ], "John", "Check JSON: first, name" );
|
assert.strictEqual( json[ 0 ].name, "John", "Check JSON: first, name" );
|
||||||
assert.strictEqual( json[ 0 ][ "age" ], 21, "Check JSON: first, age" );
|
assert.strictEqual( json[ 0 ].age, 21, "Check JSON: first, age" );
|
||||||
assert.strictEqual( json[ 1 ][ "name" ], "Peter", "Check JSON: second, name" );
|
assert.strictEqual( json[ 1 ].name, "Peter", "Check JSON: second, name" );
|
||||||
assert.strictEqual( json[ 1 ][ "age" ], 25, "Check JSON: second, age" );
|
assert.strictEqual( json[ 1 ].age, 25, "Check JSON: second, age" );
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -2683,9 +2692,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
assert.expect( 2 );
|
assert.expect( 2 );
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
jQuery.getJSON( url( "mock.php?action=json" ), function( json ) {
|
jQuery.getJSON( url( "mock.php?action=json" ), function( json ) {
|
||||||
if ( json && json[ "data" ] ) {
|
if ( json && json.data ) {
|
||||||
assert.strictEqual( json[ "data" ][ "lang" ], "en", "Check JSON: lang" );
|
assert.strictEqual( json.data.lang, "en", "Check JSON: lang" );
|
||||||
assert.strictEqual( json[ "data" ].length, 25, "Check JSON: length" );
|
assert.strictEqual( json.data.length, 25, "Check JSON: length" );
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@ -2725,7 +2734,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
|
|
||||||
Globals.register( "testBar" );
|
Globals.register( "testBar" );
|
||||||
jQuery.getScript( url( "mock.php?action=testbar" ), function() {
|
jQuery.getScript( url( "mock.php?action=testbar" ), function() {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Check if script was evaluated" );
|
assert.strictEqual( window.testBar, "bar", "Check if script was evaluated" );
|
||||||
done();
|
done();
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@ -2756,7 +2765,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
jQuery.getScript( {
|
jQuery.getScript( {
|
||||||
url: url( "mock.php?action=testbar" ),
|
url: url( "mock.php?action=testbar" ),
|
||||||
success: function() {
|
success: function() {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Check if script was evaluated" );
|
assert.strictEqual( window.testBar, "bar", "Check if script was evaluated" );
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
@ -2858,7 +2867,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
assert.expect( 7 );
|
assert.expect( 7 );
|
||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
var verifyEvaluation = function() {
|
var verifyEvaluation = function() {
|
||||||
assert.strictEqual( window[ "testBar" ], "bar", "Check if script src was evaluated after load" );
|
assert.strictEqual( window.testBar, "bar", "Check if script src was evaluated after load" );
|
||||||
assert.strictEqual( jQuery( "#ap" ).html(), "bar", "Check if script evaluation has modified DOM" );
|
assert.strictEqual( jQuery( "#ap" ).html(), "bar", "Check if script evaluation has modified DOM" );
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
@ -2869,7 +2878,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
jQuery( "#first" ).load( url( "mock.php?action=testHTML&baseURL=" + baseURL ), function() {
|
jQuery( "#first" ).load( url( "mock.php?action=testHTML&baseURL=" + baseURL ), function() {
|
||||||
assert.ok( jQuery( "#first" ).html().match( /^html text/ ), "Check content after loading html" );
|
assert.ok( jQuery( "#first" ).html().match( /^html text/ ), "Check content after loading html" );
|
||||||
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
|
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
|
||||||
assert.strictEqual( window[ "testFoo" ], "foo", "Check if script was evaluated after load" );
|
assert.strictEqual( window.testFoo, "foo", "Check if script was evaluated after load" );
|
||||||
setTimeout( verifyEvaluation, 600 );
|
setTimeout( verifyEvaluation, 600 );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
@ -2881,7 +2890,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
|
|
||||||
jQuery( "#first" ).load( url( "test2.html" ), function() {
|
jQuery( "#first" ).load( url( "test2.html" ), function() {
|
||||||
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
|
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
|
||||||
assert.strictEqual( window[ "testFoo" ], "foo", "Check if script was evaluated after load" );
|
assert.strictEqual( window.testFoo, "foo", "Check if script was evaluated after load" );
|
||||||
done();
|
done();
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -239,7 +239,7 @@ QUnit.test( "attr(Hash)", function( assert ) {
|
|||||||
assert.equal(
|
assert.equal(
|
||||||
jQuery( "#text1" ).attr( {
|
jQuery( "#text1" ).attr( {
|
||||||
"value": function() {
|
"value": function() {
|
||||||
return this[ "id" ];
|
return this.id;
|
||||||
} } ).attr( "value" ),
|
} } ).attr( "value" ),
|
||||||
"text1",
|
"text1",
|
||||||
"Set attribute to computed value #1"
|
"Set attribute to computed value #1"
|
||||||
@ -394,11 +394,11 @@ QUnit.test( "attr(String, Object)", function( assert ) {
|
|||||||
table = jQuery( "#table" ).append( "<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>" );
|
table = jQuery( "#table" ).append( "<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>" );
|
||||||
td = table.find( "td" ).eq( 0 );
|
td = table.find( "td" ).eq( 0 );
|
||||||
td.attr( "rowspan", "2" );
|
td.attr( "rowspan", "2" );
|
||||||
assert.equal( td[ 0 ][ "rowSpan" ], 2, "Check rowspan is correctly set" );
|
assert.equal( td[ 0 ].rowSpan, 2, "Check rowspan is correctly set" );
|
||||||
td.attr( "colspan", "2" );
|
td.attr( "colspan", "2" );
|
||||||
assert.equal( td[ 0 ][ "colSpan" ], 2, "Check colspan is correctly set" );
|
assert.equal( td[ 0 ].colSpan, 2, "Check colspan is correctly set" );
|
||||||
table.attr( "cellspacing", "2" );
|
table.attr( "cellspacing", "2" );
|
||||||
assert.equal( table[ 0 ][ "cellSpacing" ], "2", "Check cellspacing is correctly set" );
|
assert.equal( table[ 0 ].cellSpacing, "2", "Check cellspacing is correctly set" );
|
||||||
|
|
||||||
assert.equal( jQuery( "#area1" ).attr( "value" ), undefined, "Value attribute is distinct from value property." );
|
assert.equal( jQuery( "#area1" ).attr( "value" ), undefined, "Value attribute is distinct from value property." );
|
||||||
|
|
||||||
@ -456,6 +456,7 @@ QUnit.test( "attr(String, Object)", function( assert ) {
|
|||||||
|
|
||||||
$radio = jQuery( "<input>", {
|
$radio = jQuery( "<input>", {
|
||||||
"value": "sup",
|
"value": "sup",
|
||||||
|
|
||||||
// Use uppercase here to ensure the type
|
// Use uppercase here to ensure the type
|
||||||
// attrHook is still used
|
// attrHook is still used
|
||||||
"TYPE": "radio"
|
"TYPE": "radio"
|
||||||
@ -724,9 +725,9 @@ QUnit.test( "prop(String, Object) on null/undefined", function( assert ) {
|
|||||||
$body = jQuery( body );
|
$body = jQuery( body );
|
||||||
|
|
||||||
assert.ok( $body.prop( "nextSibling" ) === null, "Make sure a null expando returns null" );
|
assert.ok( $body.prop( "nextSibling" ) === null, "Make sure a null expando returns null" );
|
||||||
body[ "foo" ] = "bar";
|
body.foo = "bar";
|
||||||
assert.equal( $body.prop( "foo" ), "bar", "Make sure the expando is preferred over the dom attribute" );
|
assert.equal( $body.prop( "foo" ), "bar", "Make sure the expando is preferred over the dom attribute" );
|
||||||
body[ "foo" ] = undefined;
|
body.foo = undefined;
|
||||||
assert.ok( $body.prop( "foo" ) === undefined, "Make sure the expando is preferred over the dom attribute, even if undefined" );
|
assert.ok( $body.prop( "foo" ) === undefined, "Make sure the expando is preferred over the dom attribute, even if undefined" );
|
||||||
|
|
||||||
select = document.createElement( "select" );
|
select = document.createElement( "select" );
|
||||||
@ -871,7 +872,7 @@ QUnit.test( "removeProp(String)", function( assert ) {
|
|||||||
obj = {};
|
obj = {};
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
jQuery( "#firstp" ).prop( "nonexisting", "foo" ).removeProp( "nonexisting" )[ 0 ][ "nonexisting" ],
|
jQuery( "#firstp" ).prop( "nonexisting", "foo" ).removeProp( "nonexisting" )[ 0 ].nonexisting,
|
||||||
undefined,
|
undefined,
|
||||||
"removeprop works correctly on DOM element nodes"
|
"removeprop works correctly on DOM element nodes"
|
||||||
);
|
);
|
||||||
@ -879,12 +880,12 @@ QUnit.test( "removeProp(String)", function( assert ) {
|
|||||||
jQuery.each( [ document, obj ], function( i, ele ) {
|
jQuery.each( [ document, obj ], function( i, ele ) {
|
||||||
var $ele = jQuery( ele );
|
var $ele = jQuery( ele );
|
||||||
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
|
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
|
||||||
assert.strictEqual( ele[ "nonexisting" ], undefined, "removeProp works correctly on non DOM element nodes (bug trac-7500)." );
|
assert.strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug trac-7500)." );
|
||||||
} );
|
} );
|
||||||
jQuery.each( [ commentNode, textNode, attributeNode ], function( i, ele ) {
|
jQuery.each( [ commentNode, textNode, attributeNode ], function( i, ele ) {
|
||||||
var $ele = jQuery( ele );
|
var $ele = jQuery( ele );
|
||||||
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
|
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
|
||||||
assert.strictEqual( ele[ "nonexisting" ], undefined, "removeProp works correctly on non DOM element nodes (bug trac-7500)." );
|
assert.strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug trac-7500)." );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -1131,7 +1132,7 @@ QUnit.test( "val(select) after form.reset() (Bug trac-2551)", function( assert )
|
|||||||
|
|
||||||
jQuery( "#kkk" ).val( "gf" );
|
jQuery( "#kkk" ).val( "gf" );
|
||||||
|
|
||||||
document[ "kk" ].reset();
|
document.kk.reset();
|
||||||
|
|
||||||
assert.equal( jQuery( "#kkk" )[ 0 ].value, "cf", "Check value of select after form reset." );
|
assert.equal( jQuery( "#kkk" )[ 0 ].value, "cf", "Check value of select after form reset." );
|
||||||
assert.equal( jQuery( "#kkk" ).val(), "cf", "Check value of select after form reset." );
|
assert.equal( jQuery( "#kkk" ).val(), "cf", "Check value of select after form reset." );
|
||||||
|
@ -19,6 +19,7 @@ var output,
|
|||||||
outputA = addToOutput( "A" ),
|
outputA = addToOutput( "A" ),
|
||||||
outputB = addToOutput( "B" ),
|
outputB = addToOutput( "B" ),
|
||||||
outputC = addToOutput( "C" ),
|
outputC = addToOutput( "C" ),
|
||||||
|
/* eslint-disable key-spacing */
|
||||||
tests = {
|
tests = {
|
||||||
"": "XABC X XABCABCC X XBB X XABA X XX",
|
"": "XABC X XABCABCC X XBB X XABA X XX",
|
||||||
"once": "XABC X X X X X XABA X XX",
|
"once": "XABC X X X X X XABA X XX",
|
||||||
@ -227,7 +228,9 @@ jQuery.each( tests, function( strFlags, resultString ) {
|
|||||||
// Return false
|
// Return false
|
||||||
output = "X";
|
output = "X";
|
||||||
cblist = jQuery.Callbacks( flags );
|
cblist = jQuery.Callbacks( flags );
|
||||||
cblist.add( outputA, function() { return false; }, outputB );
|
cblist.add( outputA, function() {
|
||||||
|
return false;
|
||||||
|
}, outputB );
|
||||||
cblist.add( outputA );
|
cblist.add( outputA );
|
||||||
cblist.fire();
|
cblist.fire();
|
||||||
assert.strictEqual( output, results.shift(), "Callback returning false" );
|
assert.strictEqual( output, results.shift(), "Callback returning false" );
|
||||||
@ -269,7 +272,7 @@ QUnit.test( "jQuery.Callbacks( options ) - options are copied", function( assert
|
|||||||
fn = function() {
|
fn = function() {
|
||||||
assert.ok( !( count++ ), "called once" );
|
assert.ok( !( count++ ), "called once" );
|
||||||
};
|
};
|
||||||
options[ "unique" ] = false;
|
options.unique = false;
|
||||||
cb.add( fn, fn );
|
cb.add( fn, fn );
|
||||||
cb.fire();
|
cb.fire();
|
||||||
} );
|
} );
|
||||||
@ -364,7 +367,9 @@ QUnit.test( "jQuery.Callbacks() - disabled callback doesn't fire (gh-1790)", fun
|
|||||||
|
|
||||||
var cb = jQuery.Callbacks(),
|
var cb = jQuery.Callbacks(),
|
||||||
fired = false,
|
fired = false,
|
||||||
shot = function() { fired = true; };
|
shot = function() {
|
||||||
|
fired = true;
|
||||||
|
};
|
||||||
|
|
||||||
cb.disable();
|
cb.disable();
|
||||||
cb.empty();
|
cb.empty();
|
||||||
@ -379,8 +384,12 @@ QUnit.test( "jQuery.Callbacks() - list with memory stays locked (gh-3469)", func
|
|||||||
|
|
||||||
var cb = jQuery.Callbacks( "memory" ),
|
var cb = jQuery.Callbacks( "memory" ),
|
||||||
fired = 0,
|
fired = 0,
|
||||||
count1 = function() { fired += 1; },
|
count1 = function() {
|
||||||
count2 = function() { fired += 10; };
|
fired += 1;
|
||||||
|
},
|
||||||
|
count2 = function() {
|
||||||
|
fired += 10;
|
||||||
|
};
|
||||||
|
|
||||||
cb.add( count1 );
|
cb.add( count1 );
|
||||||
cb.fire();
|
cb.fire();
|
||||||
|
@ -38,19 +38,21 @@ QUnit.test( "jQuery()", function( assert ) {
|
|||||||
// few here but beware of modular builds where these methods may be excluded.
|
// few here but beware of modular builds where these methods may be excluded.
|
||||||
if ( includesModule( "deprecated" ) ) {
|
if ( includesModule( "deprecated" ) ) {
|
||||||
expected++;
|
expected++;
|
||||||
attrObj[ "click" ] = function() { assert.ok( exec, "Click executed." ); };
|
attrObj.click = function() {
|
||||||
|
assert.ok( exec, "Click executed." );
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if ( includesModule( "dimensions" ) ) {
|
if ( includesModule( "dimensions" ) ) {
|
||||||
expected++;
|
expected++;
|
||||||
attrObj[ "width" ] = 10;
|
attrObj.width = 10;
|
||||||
}
|
}
|
||||||
if ( includesModule( "offset" ) ) {
|
if ( includesModule( "offset" ) ) {
|
||||||
expected++;
|
expected++;
|
||||||
attrObj[ "offset" ] = { "top": 1, "left": 1 };
|
attrObj.offset = { "top": 1, "left": 1 };
|
||||||
}
|
}
|
||||||
if ( includesModule( "css" ) ) {
|
if ( includesModule( "css" ) ) {
|
||||||
expected += 2;
|
expected += 2;
|
||||||
attrObj[ "css" ] = { "paddingLeft": 1, "paddingRight": 1 };
|
attrObj.css = { "paddingLeft": 1, "paddingRight": 1 };
|
||||||
}
|
}
|
||||||
if ( includesModule( "attributes" ) ) {
|
if ( includesModule( "attributes" ) ) {
|
||||||
expected++;
|
expected++;
|
||||||
@ -216,17 +218,17 @@ QUnit.test( "noConflict", function( assert ) {
|
|||||||
var $$ = jQuery;
|
var $$ = jQuery;
|
||||||
|
|
||||||
assert.strictEqual( jQuery, jQuery.noConflict(), "noConflict returned the jQuery object" );
|
assert.strictEqual( jQuery, jQuery.noConflict(), "noConflict returned the jQuery object" );
|
||||||
assert.strictEqual( window[ "jQuery" ], $$, "Make sure jQuery wasn't touched." );
|
assert.strictEqual( window.jQuery, $$, "Make sure jQuery wasn't touched." );
|
||||||
assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
|
assert.strictEqual( window.$, original$, "Make sure $ was reverted." );
|
||||||
|
|
||||||
jQuery = $ = $$;
|
jQuery = $ = $$;
|
||||||
|
|
||||||
assert.strictEqual( jQuery.noConflict( true ), $$, "noConflict returned the jQuery object" );
|
assert.strictEqual( jQuery.noConflict( true ), $$, "noConflict returned the jQuery object" );
|
||||||
assert.strictEqual( window[ "jQuery" ], originaljQuery, "Make sure jQuery was reverted." );
|
assert.strictEqual( window.jQuery, originaljQuery, "Make sure jQuery was reverted." );
|
||||||
assert.strictEqual( window[ "$" ], original$, "Make sure $ was reverted." );
|
assert.strictEqual( window.$, original$, "Make sure $ was reverted." );
|
||||||
assert.ok( $$().pushStack( [] ), "Make sure that jQuery still works." );
|
assert.ok( $$().pushStack( [] ), "Make sure that jQuery still works." );
|
||||||
|
|
||||||
window[ "jQuery" ] = jQuery = $$;
|
window.jQuery = jQuery = $$;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( "isPlainObject", function( assert ) {
|
QUnit.test( "isPlainObject", function( assert ) {
|
||||||
@ -274,7 +276,7 @@ QUnit.test( "isPlainObject", function( assert ) {
|
|||||||
|
|
||||||
// Makes the function a little more realistic
|
// Makes the function a little more realistic
|
||||||
// (and harder to detect, incidentally)
|
// (and harder to detect, incidentally)
|
||||||
fn.prototype[ "someMethod" ] = function() {};
|
fn.prototype.someMethod = function() {};
|
||||||
|
|
||||||
// Again, instantiated objects shouldn't be matched
|
// Again, instantiated objects shouldn't be matched
|
||||||
assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" );
|
assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" );
|
||||||
@ -431,10 +433,10 @@ QUnit.test( "XSS via location.hash", function( assert ) {
|
|||||||
var done = assert.async();
|
var done = assert.async();
|
||||||
assert.expect( 1 );
|
assert.expect( 1 );
|
||||||
|
|
||||||
jQuery[ "_check9521" ] = function( x ) {
|
jQuery._check9521 = function( x ) {
|
||||||
assert.ok( x, "script called from #id-like selector with inline handler" );
|
assert.ok( x, "script called from #id-like selector with inline handler" );
|
||||||
jQuery( "#check9521" ).remove();
|
jQuery( "#check9521" ).remove();
|
||||||
delete jQuery[ "_check9521" ];
|
delete jQuery._check9521;
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
@ -442,7 +444,7 @@ QUnit.test( "XSS via location.hash", function( assert ) {
|
|||||||
// This throws an error because it's processed like an id
|
// This throws an error because it's processed like an id
|
||||||
jQuery( "#<img id='check9521' src='no-such-.gif' onerror='jQuery._check9521(false)'>" ).appendTo( "#qunit-fixture" );
|
jQuery( "#<img id='check9521' src='no-such-.gif' onerror='jQuery._check9521(false)'>" ).appendTo( "#qunit-fixture" );
|
||||||
} catch ( err ) {
|
} catch ( err ) {
|
||||||
jQuery[ "_check9521" ]( true );
|
jQuery._check9521( true );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -451,12 +453,12 @@ QUnit.test( "jQuery('html')", function( assert ) {
|
|||||||
|
|
||||||
var s, div, j;
|
var s, div, j;
|
||||||
|
|
||||||
jQuery[ "foo" ] = false;
|
jQuery.foo = false;
|
||||||
s = jQuery( "<script>jQuery.foo='test';</script>" )[ 0 ];
|
s = jQuery( "<script>jQuery.foo='test';</script>" )[ 0 ];
|
||||||
assert.ok( s, "Creating a script" );
|
assert.ok( s, "Creating a script" );
|
||||||
assert.ok( !jQuery[ "foo" ], "Make sure the script wasn't executed prematurely" );
|
assert.ok( !jQuery.foo, "Make sure the script wasn't executed prematurely" );
|
||||||
jQuery( "body" ).append( "<script>jQuery.foo='test';</script>" );
|
jQuery( "body" ).append( "<script>jQuery.foo='test';</script>" );
|
||||||
assert.ok( jQuery[ "foo" ], "Executing a script's contents in the right context" );
|
assert.ok( jQuery.foo, "Executing a script's contents in the right context" );
|
||||||
|
|
||||||
// Test multi-line HTML
|
// Test multi-line HTML
|
||||||
div = jQuery( "<div>\r\nsome text\n<p>some p</p>\nmore text\r\n</div>" )[ 0 ];
|
div = jQuery( "<div>\r\nsome text\n<p>some p</p>\nmore text\r\n</div>" )[ 0 ];
|
||||||
@ -634,7 +636,9 @@ QUnit.test( "each(Function)", function( assert ) {
|
|||||||
var div, pass, i;
|
var div, pass, i;
|
||||||
|
|
||||||
div = jQuery( "div" );
|
div = jQuery( "div" );
|
||||||
div.each( function() {this.foo = "zoo";} );
|
div.each( function() {
|
||||||
|
this.foo = "zoo";
|
||||||
|
} );
|
||||||
pass = true;
|
pass = true;
|
||||||
for ( i = 0; i < div.length; i++ ) {
|
for ( i = 0; i < div.length; i++ ) {
|
||||||
if ( div.get( i ).foo !== "zoo" ) {
|
if ( div.get( i ).foo !== "zoo" ) {
|
||||||
@ -740,8 +744,13 @@ QUnit.test( "jQuery.map", function( assert ) {
|
|||||||
|
|
||||||
result = {
|
result = {
|
||||||
Zero: function() {},
|
Zero: function() {},
|
||||||
One: function( a ) { a = a; },
|
One: function( a ) {
|
||||||
Two: function( a, b ) { a = a; b = b; }
|
a = a;
|
||||||
|
},
|
||||||
|
Two: function( a, b ) {
|
||||||
|
a = a;
|
||||||
|
b = b;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
callback = function( v, k ) {
|
callback = function( v, k ) {
|
||||||
assert.equal( k, "foo", label + "-argument function treated like object" );
|
assert.equal( k, "foo", label + "-argument function treated like object" );
|
||||||
@ -1000,25 +1009,25 @@ QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
|
|||||||
assert.deepEqual( options, optionsCopy, "Check if not modified: options must not be modified" );
|
assert.deepEqual( options, optionsCopy, "Check if not modified: options must not be modified" );
|
||||||
|
|
||||||
jQuery.extend( true, deep1, deep2 );
|
jQuery.extend( true, deep1, deep2 );
|
||||||
assert.deepEqual( deep1[ "foo" ], deepmerged[ "foo" ], "Check if foo: settings must be extended" );
|
assert.deepEqual( deep1.foo, deepmerged.foo, "Check if foo: settings must be extended" );
|
||||||
assert.deepEqual( deep2[ "foo" ], deep2copy[ "foo" ], "Check if not deep2: options must not be modified" );
|
assert.deepEqual( deep2.foo, deep2copy.foo, "Check if not deep2: options must not be modified" );
|
||||||
assert.equal( deep1[ "foo2" ], document, "Make sure that a deep clone was not attempted on the document" );
|
assert.equal( deep1.foo2, document, "Make sure that a deep clone was not attempted on the document" );
|
||||||
|
|
||||||
assert.ok( jQuery.extend( true, {}, nestedarray )[ "arr" ] !== arr, "Deep extend of object must clone child array" );
|
assert.ok( jQuery.extend( true, {}, nestedarray ).arr !== arr, "Deep extend of object must clone child array" );
|
||||||
|
|
||||||
// trac-5991
|
// trac-5991
|
||||||
assert.ok( Array.isArray( jQuery.extend( true, { "arr": {} }, nestedarray )[ "arr" ] ), "Cloned array have to be an Array" );
|
assert.ok( Array.isArray( jQuery.extend( true, { "arr": {} }, nestedarray ).arr ), "Cloned array have to be an Array" );
|
||||||
assert.ok( jQuery.isPlainObject( jQuery.extend( true, { "arr": arr }, { "arr": {} } )[ "arr" ] ), "Cloned object have to be an plain object" );
|
assert.ok( jQuery.isPlainObject( jQuery.extend( true, { "arr": arr }, { "arr": {} } ).arr ), "Cloned object have to be an plain object" );
|
||||||
|
|
||||||
empty = {};
|
empty = {};
|
||||||
optionsWithLength = { "foo": { "length": -1 } };
|
optionsWithLength = { "foo": { "length": -1 } };
|
||||||
jQuery.extend( true, empty, optionsWithLength );
|
jQuery.extend( true, empty, optionsWithLength );
|
||||||
assert.deepEqual( empty[ "foo" ], optionsWithLength[ "foo" ], "The length property must copy correctly" );
|
assert.deepEqual( empty.foo, optionsWithLength.foo, "The length property must copy correctly" );
|
||||||
|
|
||||||
empty = {};
|
empty = {};
|
||||||
optionsWithDate = { "foo": { "date": new Date() } };
|
optionsWithDate = { "foo": { "date": new Date() } };
|
||||||
jQuery.extend( true, empty, optionsWithDate );
|
jQuery.extend( true, empty, optionsWithDate );
|
||||||
assert.deepEqual( empty[ "foo" ], optionsWithDate[ "foo" ], "Dates copy correctly" );
|
assert.deepEqual( empty.foo, optionsWithDate.foo, "Dates copy correctly" );
|
||||||
|
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
myKlass = function() {};
|
myKlass = function() {};
|
||||||
@ -1026,13 +1035,13 @@ QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
|
|||||||
optionsWithCustomObject = { "foo": { "date": customObject } };
|
optionsWithCustomObject = { "foo": { "date": customObject } };
|
||||||
empty = {};
|
empty = {};
|
||||||
jQuery.extend( true, empty, optionsWithCustomObject );
|
jQuery.extend( true, empty, optionsWithCustomObject );
|
||||||
assert.ok( empty[ "foo" ] && empty[ "foo" ][ "date" ] === customObject, "Custom objects copy correctly (no methods)" );
|
assert.ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly (no methods)" );
|
||||||
|
|
||||||
// Makes the class a little more realistic
|
// Makes the class a little more realistic
|
||||||
myKlass.prototype = { "someMethod": function() {} };
|
myKlass.prototype = { "someMethod": function() {} };
|
||||||
empty = {};
|
empty = {};
|
||||||
jQuery.extend( true, empty, optionsWithCustomObject );
|
jQuery.extend( true, empty, optionsWithCustomObject );
|
||||||
assert.ok( empty[ "foo" ] && empty[ "foo" ][ "date" ] === customObject, "Custom objects copy correctly" );
|
assert.ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly" );
|
||||||
|
|
||||||
MyNumber = Number;
|
MyNumber = Number;
|
||||||
|
|
||||||
@ -1040,13 +1049,13 @@ QUnit.test( "jQuery.extend(Object, Object)", function( assert ) {
|
|||||||
assert.ok( parseInt( ret.foo, 10 ) === 5, "Wrapped numbers copy correctly" );
|
assert.ok( parseInt( ret.foo, 10 ) === 5, "Wrapped numbers copy correctly" );
|
||||||
|
|
||||||
nullUndef = jQuery.extend( {}, options, { "xnumber2": null } );
|
nullUndef = jQuery.extend( {}, options, { "xnumber2": null } );
|
||||||
assert.ok( nullUndef[ "xnumber2" ] === null, "Check to make sure null values are copied" );
|
assert.ok( nullUndef.xnumber2 === null, "Check to make sure null values are copied" );
|
||||||
|
|
||||||
nullUndef = jQuery.extend( {}, options, { "xnumber2": undefined } );
|
nullUndef = jQuery.extend( {}, options, { "xnumber2": undefined } );
|
||||||
assert.ok( nullUndef[ "xnumber2" ] === options[ "xnumber2" ], "Check to make sure undefined values are not copied" );
|
assert.ok( nullUndef.xnumber2 === options.xnumber2, "Check to make sure undefined values are not copied" );
|
||||||
|
|
||||||
nullUndef = jQuery.extend( {}, options, { "xnumber0": null } );
|
nullUndef = jQuery.extend( {}, options, { "xnumber0": null } );
|
||||||
assert.ok( nullUndef[ "xnumber0" ] === null, "Check to make sure null values are inserted" );
|
assert.ok( nullUndef.xnumber0 === null, "Check to make sure null values are inserted" );
|
||||||
|
|
||||||
target = {};
|
target = {};
|
||||||
recursive = { foo: target, bar: 5 };
|
recursive = { foo: target, bar: 5 };
|
||||||
@ -1173,8 +1182,13 @@ QUnit.test( "jQuery.each(Object,Function)", function( assert ) {
|
|||||||
|
|
||||||
seen = {
|
seen = {
|
||||||
Zero: function() {},
|
Zero: function() {},
|
||||||
One: function( a ) { a = a; },
|
One: function( a ) {
|
||||||
Two: function( a, b ) { a = a; b = b; }
|
a = a;
|
||||||
|
},
|
||||||
|
Two: function( a, b ) {
|
||||||
|
a = a;
|
||||||
|
b = b;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
callback = function( k ) {
|
callback = function( k ) {
|
||||||
assert.equal( k, "foo", label + "-argument function treated like object" );
|
assert.equal( k, "foo", label + "-argument function treated like object" );
|
||||||
@ -1283,7 +1297,9 @@ QUnit.test( "jQuery.makeArray", function( assert ) {
|
|||||||
|
|
||||||
assert.equal( jQuery.makeArray( document.getElementsByName( "PWD" ) ).slice( 0, 1 )[ 0 ].name, "PWD", "Pass makeArray a nodelist" );
|
assert.equal( jQuery.makeArray( document.getElementsByName( "PWD" ) ).slice( 0, 1 )[ 0 ].name, "PWD", "Pass makeArray a nodelist" );
|
||||||
|
|
||||||
assert.equal( ( function() { return jQuery.makeArray( arguments ); } )( 1, 2 ).join( "" ), "12", "Pass makeArray an arguments array" );
|
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" );
|
||||||
|
|
||||||
@ -1302,7 +1318,9 @@ QUnit.test( "jQuery.makeArray", function( assert ) {
|
|||||||
assert.ok( !!jQuery.makeArray( document.documentElement.childNodes ).slice( 0, 1 )[ 0 ].nodeName, "Pass makeArray a childNodes array" );
|
assert.ok( !!jQuery.makeArray( document.documentElement.childNodes ).slice( 0, 1 )[ 0 ].nodeName, "Pass makeArray a childNodes array" );
|
||||||
|
|
||||||
// function, is tricky as it has length
|
// function, is tricky as it has length
|
||||||
assert.equal( jQuery.makeArray( function() { return 1;} )[ 0 ](), 1, "Pass makeArray a function" );
|
assert.equal( jQuery.makeArray( function() {
|
||||||
|
return 1;
|
||||||
|
} )[ 0 ](), 1, "Pass makeArray a function" );
|
||||||
|
|
||||||
//window, also has length
|
//window, also has length
|
||||||
assert.equal( jQuery.makeArray( window )[ 0 ], window, "Pass makeArray the window" );
|
assert.equal( jQuery.makeArray( window )[ 0 ], window, "Pass makeArray the window" );
|
||||||
|
@ -321,8 +321,7 @@ QUnit.test( "css(String, Object)", function( assert ) {
|
|||||||
success = true;
|
success = true;
|
||||||
try {
|
try {
|
||||||
jQuery( "#foo" ).css( "backgroundColor", "rgba(0, 0, 0, 0.1)" );
|
jQuery( "#foo" ).css( "backgroundColor", "rgba(0, 0, 0, 0.1)" );
|
||||||
}
|
} catch ( e ) {
|
||||||
catch ( e ) {
|
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
assert.ok( success, "Setting RGBA values does not throw Error (trac-5509)" );
|
assert.ok( success, "Setting RGBA values does not throw Error (trac-5509)" );
|
||||||
@ -1221,6 +1220,7 @@ QUnit.test( "Do not append px (trac-9548, trac-12990, gh-2792, gh-5179)", functi
|
|||||||
|
|
||||||
$div.css( "animation-iteration-count", 2 );
|
$div.css( "animation-iteration-count", 2 );
|
||||||
if ( $div.css( "animation-iteration-count" ) !== undefined ) {
|
if ( $div.css( "animation-iteration-count" ) !== undefined ) {
|
||||||
|
|
||||||
// if $div.css( "animation-iteration-count" ) returns "1",
|
// if $div.css( "animation-iteration-count" ) returns "1",
|
||||||
// it actually returns the default value of animation-iteration-count
|
// it actually returns the default value of animation-iteration-count
|
||||||
assert.equal( $div.css( "animation-iteration-count" ), "2",
|
assert.equal( $div.css( "animation-iteration-count" ), "2",
|
||||||
@ -1788,7 +1788,7 @@ QUnit.test( "Do not throw on frame elements from css method (trac-15098)", funct
|
|||||||
if ( transformName ) {
|
if ( transformName ) {
|
||||||
assert.equal( elemStyle[ transformName ], transformVal, "setting properly-prefixed transform" );
|
assert.equal( elemStyle[ transformName ], transformVal, "setting properly-prefixed transform" );
|
||||||
}
|
}
|
||||||
assert.equal( elemStyle[ "undefined" ], undefined, "Nothing writes to node.style.undefined" );
|
assert.equal( elemStyle.undefined, undefined, "Nothing writes to node.style.undefined" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( "Don't detect fake set properties on a node when caching the prefixed version", function( assert ) {
|
QUnit.test( "Don't detect fake set properties on a node when caching the prefixed version", function( assert ) {
|
||||||
|
@ -74,14 +74,14 @@ function dataTests( elem, assert ) {
|
|||||||
|
|
||||||
assert.strictEqual( jQuery.hasData( elem ), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" );
|
assert.strictEqual( jQuery.hasData( elem ), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" );
|
||||||
|
|
||||||
dataObj[ "foo" ] = "bar";
|
dataObj.foo = "bar";
|
||||||
assert.equal( jQuery.data( elem, "foo" ), "bar", "Data is readable by jQuery.data when set directly on a returned data object" );
|
assert.equal( jQuery.data( elem, "foo" ), "bar", "Data is readable by jQuery.data when set directly on a returned data object" );
|
||||||
|
|
||||||
assert.strictEqual( jQuery.hasData( elem ), true, "jQuery.hasData agrees data exists when data exists" );
|
assert.strictEqual( jQuery.hasData( elem ), true, "jQuery.hasData agrees data exists when data exists" );
|
||||||
|
|
||||||
jQuery.data( elem, "foo", "baz" );
|
jQuery.data( elem, "foo", "baz" );
|
||||||
assert.equal( jQuery.data( elem, "foo" ), "baz", "Data can be changed by jQuery.data" );
|
assert.equal( jQuery.data( elem, "foo" ), "baz", "Data can be changed by jQuery.data" );
|
||||||
assert.equal( dataObj[ "foo" ], "baz", "Changes made through jQuery.data propagate to referenced data object" );
|
assert.equal( dataObj.foo, "baz", "Changes made through jQuery.data propagate to referenced data object" );
|
||||||
|
|
||||||
jQuery.data( elem, "foo", undefined );
|
jQuery.data( elem, "foo", undefined );
|
||||||
assert.equal( jQuery.data( elem, "foo" ), "baz", "Data is not unset by passing undefined to jQuery.data" );
|
assert.equal( jQuery.data( elem, "foo" ), "baz", "Data is not unset by passing undefined to jQuery.data" );
|
||||||
@ -431,8 +431,8 @@ QUnit.test( ".data(Object)", function( assert ) {
|
|||||||
|
|
||||||
jqobj.data( "test", "unset" );
|
jqobj.data( "test", "unset" );
|
||||||
jqobj.data( { "test": "in", "test2": "in2" } );
|
jqobj.data( { "test": "in", "test2": "in2" } );
|
||||||
assert.equal( jQuery.data( obj )[ "test" ], "in", "Verify setting an object on an object extends the data object" );
|
assert.equal( jQuery.data( obj ).test, "in", "Verify setting an object on an object extends the data object" );
|
||||||
assert.equal( obj[ "test2" ], undefined, "Verify setting an object on an object does not extend the object" );
|
assert.equal( obj.test2, undefined, "Verify setting an object on an object does not extend the object" );
|
||||||
|
|
||||||
// manually clean up detached elements
|
// manually clean up detached elements
|
||||||
div.remove();
|
div.remove();
|
||||||
@ -523,12 +523,12 @@ QUnit.test( ".data should follow html5 specification regarding camel casing", fu
|
|||||||
var div = jQuery( "<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>" )
|
var div = jQuery( "<div id='myObject' data-w-t-f='ftw' data-big-a-little-a='bouncing-b' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>" )
|
||||||
.prependTo( "body" );
|
.prependTo( "body" );
|
||||||
|
|
||||||
assert.equal( div.data()[ "wTF" ], "ftw", "Verify single letter data-* key" );
|
assert.equal( div.data().wTF, "ftw", "Verify single letter data-* key" );
|
||||||
assert.equal( div.data()[ "bigALittleA" ], "bouncing-b", "Verify single letter mixed data-* key" );
|
assert.equal( div.data().bigALittleA, "bouncing-b", "Verify single letter mixed data-* key" );
|
||||||
|
|
||||||
assert.equal( div.data()[ "foo" ], "a", "Verify single word data-* key" );
|
assert.equal( div.data().foo, "a", "Verify single word data-* key" );
|
||||||
assert.equal( div.data()[ "fooBar" ], "b", "Verify multiple word data-* key" );
|
assert.equal( div.data().fooBar, "b", "Verify multiple word data-* key" );
|
||||||
assert.equal( div.data()[ "fooBarBaz" ], "c", "Verify multiple word data-* key" );
|
assert.equal( div.data().fooBarBaz, "c", "Verify multiple word data-* key" );
|
||||||
|
|
||||||
assert.equal( div.data( "foo" ), "a", "Verify single word data-* key" );
|
assert.equal( div.data( "foo" ), "a", "Verify single word data-* key" );
|
||||||
assert.equal( div.data( "fooBar" ), "b", "Verify multiple word data-* key" );
|
assert.equal( div.data( "fooBar" ), "b", "Verify multiple word data-* key" );
|
||||||
|
@ -108,7 +108,9 @@ QUnit.test( "jQuery.Deferred.then - filtering (done)", function( assert ) {
|
|||||||
piped = defer.then( function( a, b ) {
|
piped = defer.then( function( a, b ) {
|
||||||
return a * b;
|
return a * b;
|
||||||
} ),
|
} ),
|
||||||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 3 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
piped.done( function( result ) {
|
piped.done( function( result ) {
|
||||||
value3 = result;
|
value3 = result;
|
||||||
@ -145,7 +147,9 @@ QUnit.test( "jQuery.Deferred.then - filtering (fail)", function( assert ) {
|
|||||||
piped = defer.then( null, function( a, b ) {
|
piped = defer.then( null, function( a, b ) {
|
||||||
return a * b;
|
return a * b;
|
||||||
} ),
|
} ),
|
||||||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 3 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
piped.done( function( result ) {
|
piped.done( function( result ) {
|
||||||
value3 = result;
|
value3 = result;
|
||||||
@ -178,10 +182,12 @@ QUnit.test( "jQuery.Deferred.catch", function( assert ) {
|
|||||||
|
|
||||||
var value1, value2, value3,
|
var value1, value2, value3,
|
||||||
defer = jQuery.Deferred(),
|
defer = jQuery.Deferred(),
|
||||||
piped = defer[ "catch" ]( function( a, b ) {
|
piped = defer.catch( function( a, b ) {
|
||||||
return a * b;
|
return a * b;
|
||||||
} ),
|
} ),
|
||||||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 3 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
piped.done( function( result ) {
|
piped.done( function( result ) {
|
||||||
value3 = result;
|
value3 = result;
|
||||||
@ -192,18 +198,18 @@ QUnit.test( "jQuery.Deferred.catch", function( assert ) {
|
|||||||
value2 = b;
|
value2 = b;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
defer.reject( 2, 3 )[ "catch" ]( function() {
|
defer.reject( 2, 3 ).catch( function() {
|
||||||
assert.strictEqual( value1, 2, "first reject value ok" );
|
assert.strictEqual( value1, 2, "first reject value ok" );
|
||||||
assert.strictEqual( value2, 3, "second reject value ok" );
|
assert.strictEqual( value2, 3, "second reject value ok" );
|
||||||
assert.strictEqual( value3, 6, "result of filter ok" );
|
assert.strictEqual( value3, 6, "result of filter ok" );
|
||||||
done.pop().call();
|
done.pop().call();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
jQuery.Deferred().resolve()[ "catch" ]( function() {
|
jQuery.Deferred().resolve().catch( function() {
|
||||||
assert.ok( false, "then should not be called on resolve" );
|
assert.ok( false, "then should not be called on resolve" );
|
||||||
} ).then( done.pop() );
|
} ).then( done.pop() );
|
||||||
|
|
||||||
jQuery.Deferred().reject()[ "catch" ]( jQuery.noop ).done( function( value ) {
|
jQuery.Deferred().reject().catch( jQuery.noop ).done( function( value ) {
|
||||||
assert.strictEqual( value, undefined, "then fail callback can return undefined/null" );
|
assert.strictEqual( value, undefined, "then fail callback can return undefined/null" );
|
||||||
done.pop().call();
|
done.pop().call();
|
||||||
} );
|
} );
|
||||||
@ -218,7 +224,9 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - filtering (fail)", function( ass
|
|||||||
piped = defer.pipe( null, function( a, b ) {
|
piped = defer.pipe( null, function( a, b ) {
|
||||||
return a * b;
|
return a * b;
|
||||||
} ),
|
} ),
|
||||||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 3 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
piped.fail( function( result ) {
|
piped.fail( function( result ) {
|
||||||
value3 = result;
|
value3 = result;
|
||||||
@ -416,7 +424,9 @@ QUnit.test( "jQuery.Deferred.then - context", function( assert ) {
|
|||||||
|
|
||||||
var defer, piped, defer2, piped2,
|
var defer, piped, defer2, piped2,
|
||||||
context = { custom: true },
|
context = { custom: true },
|
||||||
done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 5 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery.Deferred().resolveWith( context, [ 2 ] ).then( function( value ) {
|
jQuery.Deferred().resolveWith( context, [ 2 ] ).then( function( value ) {
|
||||||
assert.strictEqual( this, context, "custom context received by .then handler" );
|
assert.strictEqual( this, context, "custom context received by .then handler" );
|
||||||
@ -475,7 +485,9 @@ QUnit.test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
|
|||||||
|
|
||||||
var defer, piped, defer2, piped2,
|
var defer, piped, defer2, piped2,
|
||||||
context = { custom: true },
|
context = { custom: true },
|
||||||
done = jQuery.map( new Array( 5 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 5 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe( function( value ) {
|
jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe( function( value ) {
|
||||||
assert.strictEqual( this, context, "custom context received by .pipe handler" );
|
assert.strictEqual( this, context, "custom context received by .pipe handler" );
|
||||||
@ -676,7 +688,9 @@ QUnit.test( "jQuery.Deferred - 1.x/2.x compatibility", function( assert ) {
|
|||||||
|
|
||||||
var context = { id: "callback context" },
|
var context = { id: "callback context" },
|
||||||
thenable = jQuery.Deferred().resolve( "thenable fulfillment" ).promise(),
|
thenable = jQuery.Deferred().resolve( "thenable fulfillment" ).promise(),
|
||||||
done = jQuery.map( new Array( 8 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 8 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
thenable.unwrapped = false;
|
thenable.unwrapped = false;
|
||||||
|
|
||||||
@ -727,7 +741,9 @@ QUnit.test( "jQuery.Deferred.then - progress and thenables", function( assert )
|
|||||||
|
|
||||||
var trigger = jQuery.Deferred().notify(),
|
var trigger = jQuery.Deferred().notify(),
|
||||||
expectedProgress = [ "baz", "baz" ],
|
expectedProgress = [ "baz", "baz" ],
|
||||||
done = jQuery.map( new Array( 2 ), function() { return assert.async(); } ),
|
done = jQuery.map( new Array( 2 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} ),
|
||||||
failer = function( evt ) {
|
failer = function( evt ) {
|
||||||
return function() {
|
return function() {
|
||||||
assert.ok( false, "no unexpected " + evt );
|
assert.ok( false, "no unexpected " + evt );
|
||||||
@ -752,7 +768,9 @@ QUnit.test( "jQuery.Deferred - notify and resolve", function( assert ) {
|
|||||||
assert.expect( 7 );
|
assert.expect( 7 );
|
||||||
|
|
||||||
var notifiedResolved = jQuery.Deferred().notify( "foo" )/*xxx .resolve( "bar" )*/,
|
var notifiedResolved = jQuery.Deferred().notify( "foo" )/*xxx .resolve( "bar" )*/,
|
||||||
done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
|
done = jQuery.map( new Array( 3 ), function() {
|
||||||
|
return assert.async();
|
||||||
|
} );
|
||||||
|
|
||||||
notifiedResolved.progress( function( v ) {
|
notifiedResolved.progress( function( v ) {
|
||||||
assert.strictEqual( v, "foo", "progress value" );
|
assert.strictEqual( v, "foo", "progress value" );
|
||||||
@ -836,7 +854,9 @@ QUnit.test( "jQuery.when(nonThenable) - like Promise.resolve", function( assert
|
|||||||
|
|
||||||
// Support: Android 4.0 only
|
// Support: Android 4.0 only
|
||||||
// Strict mode functions invoked without .call/.apply get global-object context
|
// Strict mode functions invoked without .call/.apply get global-object context
|
||||||
defaultContext = ( function getDefaultContext() { return this; } ).call(),
|
defaultContext = ( function getDefaultContext() {
|
||||||
|
return this;
|
||||||
|
} ).call(),
|
||||||
|
|
||||||
done = assert.async( 20 );
|
done = assert.async( 20 );
|
||||||
|
|
||||||
@ -891,6 +911,7 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
|
|
||||||
var customToStringThen = {
|
var customToStringThen = {
|
||||||
then: function( onFulfilled ) {
|
then: function( onFulfilled ) {
|
||||||
|
|
||||||
// Support: Android 4.0 only
|
// Support: Android 4.0 only
|
||||||
// Strict mode functions invoked without .call/.apply get global-object context
|
// Strict mode functions invoked without .call/.apply get global-object context
|
||||||
onFulfilled.call();
|
onFulfilled.call();
|
||||||
@ -956,7 +977,9 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) {
|
|||||||
|
|
||||||
// Support: Android 4.0 only
|
// Support: Android 4.0 only
|
||||||
// Strict mode functions invoked without .call/.apply get global-object context
|
// Strict mode functions invoked without .call/.apply get global-object context
|
||||||
defaultContext = ( function getDefaultContext() { return this; } ).call(),
|
defaultContext = ( function getDefaultContext() {
|
||||||
|
return this;
|
||||||
|
} ).call(),
|
||||||
|
|
||||||
done = assert.async( numCases * 2 );
|
done = assert.async( numCases * 2 );
|
||||||
|
|
||||||
@ -1036,7 +1059,9 @@ QUnit.test( "jQuery.when(a, b) - like Promise.all", function( assert ) {
|
|||||||
|
|
||||||
// Support: Android 4.0 only
|
// Support: Android 4.0 only
|
||||||
// Strict mode functions invoked without .call/.apply get global-object context
|
// Strict mode functions invoked without .call/.apply get global-object context
|
||||||
defaultContext = ( function getDefaultContext() { return this; } ).call(),
|
defaultContext = ( function getDefaultContext() {
|
||||||
|
return this;
|
||||||
|
} ).call(),
|
||||||
|
|
||||||
done = assert.async( 98 );
|
done = assert.async( 98 );
|
||||||
|
|
||||||
|
@ -46,8 +46,12 @@ QUnit.test( "hover() mouseenter mouseleave", function( assert ) {
|
|||||||
assert.expect( 1 );
|
assert.expect( 1 );
|
||||||
|
|
||||||
var times = 0,
|
var times = 0,
|
||||||
handler1 = function() { ++times; },
|
handler1 = function() {
|
||||||
handler2 = function() { ++times; };
|
++times;
|
||||||
|
},
|
||||||
|
handler2 = function() {
|
||||||
|
++times;
|
||||||
|
};
|
||||||
|
|
||||||
jQuery( "#firstp" )
|
jQuery( "#firstp" )
|
||||||
.hover( handler1, handler2 )
|
.hover( handler1, handler2 )
|
||||||
|
52
test/unit/effects.js
vendored
52
test/unit/effects.js
vendored
@ -7,8 +7,12 @@ if ( !includesModule( "effects" ) ) {
|
|||||||
|
|
||||||
var oldRaf = window.requestAnimationFrame,
|
var oldRaf = window.requestAnimationFrame,
|
||||||
hideOptions = {
|
hideOptions = {
|
||||||
inline: function() { jQuery.style( this, "display", "none" ); },
|
inline: function() {
|
||||||
cascade: function() { this.className = "hidden"; }
|
jQuery.style( this, "display", "none" );
|
||||||
|
},
|
||||||
|
cascade: function() {
|
||||||
|
this.className = "hidden";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QUnit.module( "effects", {
|
QUnit.module( "effects", {
|
||||||
@ -981,15 +985,33 @@ jQuery.each( {
|
|||||||
num = 0;
|
num = 0;
|
||||||
|
|
||||||
// TODO: uncrowd this
|
// TODO: uncrowd this
|
||||||
if ( t_h === "show" ) { num++; }
|
if ( t_h === "show" ) {
|
||||||
if ( t_w === "show" ) { num++; }
|
num++;
|
||||||
if ( t_w === "hide" || t_w === "show" ) { num++; }
|
}
|
||||||
if ( t_h === "hide" || t_h === "show" ) { num++; }
|
if ( t_w === "show" ) {
|
||||||
if ( t_o === "hide" || t_o === "show" ) { num++; }
|
num++;
|
||||||
if ( t_w === "hide" ) { num++; }
|
}
|
||||||
if ( t_o.constructor === Number ) { num += 2; }
|
if ( t_w === "hide" || t_w === "show" ) {
|
||||||
if ( t_w.constructor === Number ) { num += 2; }
|
num++;
|
||||||
if ( t_h.constructor === Number ) { num += 2; }
|
}
|
||||||
|
if ( t_h === "hide" || t_h === "show" ) {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
if ( t_o === "hide" || t_o === "show" ) {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
if ( t_w === "hide" ) {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
if ( t_o.constructor === Number ) {
|
||||||
|
num += 2;
|
||||||
|
}
|
||||||
|
if ( t_w.constructor === Number ) {
|
||||||
|
num += 2;
|
||||||
|
}
|
||||||
|
if ( t_h.constructor === Number ) {
|
||||||
|
num += 2;
|
||||||
|
}
|
||||||
|
|
||||||
assert.expect( num );
|
assert.expect( num );
|
||||||
|
|
||||||
@ -2487,7 +2509,9 @@ QUnit.test( "Show/hide/toggle and display: inline", function( assert ) {
|
|||||||
.hide().show( N ),
|
.hide().show( N ),
|
||||||
$el.clone().data( { call: "hide+toggle", done: "inline" } ).appendTo( fixture )
|
$el.clone().data( { call: "hide+toggle", done: "inline" } ).appendTo( fixture )
|
||||||
.hide().toggle( N )
|
.hide().toggle( N )
|
||||||
], function( $clone ) { return $clone[ 0 ]; } );
|
], function( $clone ) {
|
||||||
|
return $clone[ 0 ];
|
||||||
|
} );
|
||||||
|
|
||||||
// Animations not allowed to complete
|
// Animations not allowed to complete
|
||||||
interrupted = jQuery.map( [
|
interrupted = jQuery.map( [
|
||||||
@ -2495,7 +2519,9 @@ QUnit.test( "Show/hide/toggle and display: inline", function( assert ) {
|
|||||||
$el.clone().data( { call: "toggle+stop" } ).appendTo( fixture ).toggle( N ),
|
$el.clone().data( { call: "toggle+stop" } ).appendTo( fixture ).toggle( N ),
|
||||||
$el.clone().data( { call: "hide+show+stop" } ).appendTo( fixture ).hide().show( N ),
|
$el.clone().data( { call: "hide+show+stop" } ).appendTo( fixture ).hide().show( N ),
|
||||||
$el.clone().data( { call: "hide+toggle+stop" } ).appendTo( fixture ).hide().toggle( N )
|
$el.clone().data( { call: "hide+toggle+stop" } ).appendTo( fixture ).hide().toggle( N )
|
||||||
], function( $clone ) { return $clone[ 0 ]; } );
|
], function( $clone ) {
|
||||||
|
return $clone[ 0 ];
|
||||||
|
} );
|
||||||
|
|
||||||
// All elements should be inline-block during the animation
|
// All elements should be inline-block during the animation
|
||||||
clock.tick( N / 2 );
|
clock.tick( N / 2 );
|
||||||
|
@ -224,12 +224,12 @@ QUnit.test( "on(), namespace with special add", function( assert ) {
|
|||||||
|
|
||||||
div.on( "test.a", { x: 1 }, function( e ) {
|
div.on( "test.a", { x: 1 }, function( e ) {
|
||||||
assert.ok( !!e.xyz, "Make sure that the data is getting passed through." );
|
assert.ok( !!e.xyz, "Make sure that the data is getting passed through." );
|
||||||
assert.equal( e.data[ "x" ], 1, "Make sure data is attached properly." );
|
assert.equal( e.data.x, 1, "Make sure data is attached properly." );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
div.on( "test.b", { x: 2 }, function( e ) {
|
div.on( "test.b", { x: 2 }, function( e ) {
|
||||||
assert.ok( !!e.xyz, "Make sure that the data is getting passed through." );
|
assert.ok( !!e.xyz, "Make sure that the data is getting passed through." );
|
||||||
assert.equal( e.data[ "x" ], 2, "Make sure data is attached properly." );
|
assert.equal( e.data.x, 2, "Make sure data is attached properly." );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// Should trigger 5
|
// Should trigger 5
|
||||||
@ -553,7 +553,9 @@ QUnit.test( "on(), namespaced events, cloned events", function( assert ) {
|
|||||||
} ).trigger( "tester" );
|
} ).trigger( "tester" );
|
||||||
|
|
||||||
// Make sure events stick with appendTo'd elements (which are cloned) trac-2027
|
// Make sure events stick with appendTo'd elements (which are cloned) trac-2027
|
||||||
jQuery( "<a href='#fail' class='test'>test</a>" ).on( "click", function() { return false; } ).appendTo( "#qunit-fixture" );
|
jQuery( "<a href='#fail' class='test'>test</a>" ).on( "click", function() {
|
||||||
|
return false;
|
||||||
|
} ).appendTo( "#qunit-fixture" );
|
||||||
assert.ok( jQuery( "a.test" ).eq( 0 ).triggerHandler( "click" ) === false, "Handler is bound to appendTo'd elements" );
|
assert.ok( jQuery( "a.test" ).eq( 0 ).triggerHandler( "click" ) === false, "Handler is bound to appendTo'd elements" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -704,7 +706,9 @@ QUnit.test( "on(name, false), off(name, false)", function( assert ) {
|
|||||||
assert.expect( 3 );
|
assert.expect( 3 );
|
||||||
|
|
||||||
var main = 0;
|
var main = 0;
|
||||||
jQuery( "#qunit-fixture" ).on( "click", function() { main++; } );
|
jQuery( "#qunit-fixture" ).on( "click", function() {
|
||||||
|
main++;
|
||||||
|
} );
|
||||||
jQuery( "#ap" ).trigger( "click" );
|
jQuery( "#ap" ).trigger( "click" );
|
||||||
assert.equal( main, 1, "Verify that the trigger happened correctly." );
|
assert.equal( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
|
||||||
@ -727,7 +731,9 @@ QUnit.test( "on(name, selector, false), off(name, selector, false)", function( a
|
|||||||
|
|
||||||
var main = 0;
|
var main = 0;
|
||||||
|
|
||||||
jQuery( "#qunit-fixture" ).on( "click", "#ap", function() { main++; } );
|
jQuery( "#qunit-fixture" ).on( "click", "#ap", function() {
|
||||||
|
main++;
|
||||||
|
} );
|
||||||
jQuery( "#ap" ).trigger( "click" );
|
jQuery( "#ap" ).trigger( "click" );
|
||||||
assert.equal( main, 1, "Verify that the trigger happened correctly." );
|
assert.equal( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
|
||||||
@ -766,7 +772,7 @@ QUnit.test( "on()/trigger()/off() on plain object", function( assert ) {
|
|||||||
|
|
||||||
events = jQuery._data( obj, "events" );
|
events = jQuery._data( obj, "events" );
|
||||||
assert.ok( events, "Object has events bound." );
|
assert.ok( events, "Object has events bound." );
|
||||||
assert.equal( obj[ "events" ], undefined, "Events object on plain objects is not events" );
|
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.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.handle, undefined, "Make sure that the event handler is not on the plain object." );
|
||||||
|
|
||||||
@ -785,7 +791,7 @@ QUnit.test( "on()/trigger()/off() on plain object", function( assert ) {
|
|||||||
|
|
||||||
assert.equal( obj && obj[ jQuery.expando ] &&
|
assert.equal( obj && obj[ jQuery.expando ] &&
|
||||||
obj[ jQuery.expando ][ jQuery.expando ] &&
|
obj[ jQuery.expando ][ jQuery.expando ] &&
|
||||||
obj[ jQuery.expando ][ jQuery.expando ][ "events" ], undefined, "Make sure events object is removed" );
|
obj[ jQuery.expando ][ jQuery.expando ].events, undefined, "Make sure events object is removed" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( "off(type)", function( assert ) {
|
QUnit.test( "off(type)", function( assert ) {
|
||||||
@ -938,12 +944,26 @@ QUnit.test( "trigger() bubbling", function( assert ) {
|
|||||||
|
|
||||||
var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
|
var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
|
||||||
|
|
||||||
jQuery( window ).on( "click", function() { win++; } );
|
jQuery( window ).on( "click", function() {
|
||||||
jQuery( document ).on( "click", function( e ) { if ( e.target !== document ) { doc++; } } );
|
win++;
|
||||||
jQuery( "html" ).on( "click", function() { html++; } );
|
} );
|
||||||
jQuery( "body" ).on( "click", function() { body++; } );
|
jQuery( document ).on( "click", function( e ) {
|
||||||
jQuery( "#qunit-fixture" ).on( "click", function() { main++; } );
|
if ( e.target !== document ) {
|
||||||
jQuery( "#ap" ).on( "click", function() { ap++; return false; } );
|
doc++;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
jQuery( "html" ).on( "click", function() {
|
||||||
|
html++;
|
||||||
|
} );
|
||||||
|
jQuery( "body" ).on( "click", function() {
|
||||||
|
body++;
|
||||||
|
} );
|
||||||
|
jQuery( "#qunit-fixture" ).on( "click", function() {
|
||||||
|
main++;
|
||||||
|
} );
|
||||||
|
jQuery( "#ap" ).on( "click", function() {
|
||||||
|
ap++; return false;
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery( "html" ).trigger( "click" );
|
jQuery( "html" ).trigger( "click" );
|
||||||
assert.equal( win, 1, "HTML bubble" );
|
assert.equal( win, 1, "HTML bubble" );
|
||||||
@ -1159,7 +1179,9 @@ QUnit.test( "trigger(eventObject, [data], [fn])", function( assert ) {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
assert.equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
|
assert.equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
|
||||||
|
|
||||||
event.isPropagationStopped = function() { return false; };
|
event.isPropagationStopped = function() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
assert.equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
|
assert.equal( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
|
||||||
assert.equal( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
|
assert.equal( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
|
||||||
@ -1394,7 +1416,9 @@ QUnit.test( "Submit event can be stopped (trac-11049)", function( assert ) {
|
|||||||
return false;
|
return false;
|
||||||
} )
|
} )
|
||||||
.find( "#myform input[type=submit]" )
|
.find( "#myform input[type=submit]" )
|
||||||
.each( function() { this.click(); } )
|
.each( function() {
|
||||||
|
this.click();
|
||||||
|
} )
|
||||||
.end()
|
.end()
|
||||||
.on( "submit", function() {
|
.on( "submit", function() {
|
||||||
assert.ok( false, "submit bubbled on second handler" );
|
assert.ok( false, "submit bubbled on second handler" );
|
||||||
@ -1506,10 +1530,18 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
var event, clicked, hash, called, livec, lived, livee,
|
var event, clicked, hash, called, livec, lived, livee,
|
||||||
submit = 0, div = 0, livea = 0, liveb = 0;
|
submit = 0, div = 0, livea = 0, liveb = 0;
|
||||||
|
|
||||||
jQuery( "#body" ).on( "submit", "#qunit-fixture div", function() { submit++; return false; } );
|
jQuery( "#body" ).on( "submit", "#qunit-fixture div", function() {
|
||||||
jQuery( "#body" ).on( "click", "#qunit-fixture div", function() { div++; } );
|
submit++; return false;
|
||||||
jQuery( "#body" ).on( "click", "div#nothiddendiv", function() { livea++; } );
|
} );
|
||||||
jQuery( "#body" ).on( "click", "div#nothiddendivchild", function() { liveb++; } );
|
jQuery( "#body" ).on( "click", "#qunit-fixture div", function() {
|
||||||
|
div++;
|
||||||
|
} );
|
||||||
|
jQuery( "#body" ).on( "click", "div#nothiddendiv", function() {
|
||||||
|
livea++;
|
||||||
|
} );
|
||||||
|
jQuery( "#body" ).on( "click", "div#nothiddendivchild", function() {
|
||||||
|
liveb++;
|
||||||
|
} );
|
||||||
|
|
||||||
// Nothing should trigger on the body
|
// Nothing should trigger on the body
|
||||||
jQuery( "body" ).trigger( "click" );
|
jQuery( "body" ).trigger( "click" );
|
||||||
@ -1569,7 +1601,9 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
|
|
||||||
// Make sure that stopPropagation doesn't stop live events
|
// Make sure that stopPropagation doesn't stop live events
|
||||||
submit = 0; div = 0; livea = 0; liveb = 0;
|
submit = 0; div = 0; livea = 0; liveb = 0;
|
||||||
jQuery( "#body" ).on( "click", "div#nothiddendivchild", function( e ) { liveb++; e.stopPropagation(); } );
|
jQuery( "#body" ).on( "click", "div#nothiddendivchild", function( e ) {
|
||||||
|
liveb++; e.stopPropagation();
|
||||||
|
} );
|
||||||
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
||||||
assert.equal( submit, 0, "stopPropagation Click on inner div" );
|
assert.equal( submit, 0, "stopPropagation Click on inner div" );
|
||||||
assert.equal( div, 1, "stopPropagation Click on inner div" );
|
assert.equal( div, 1, "stopPropagation Click on inner div" );
|
||||||
@ -1591,7 +1625,9 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
|
|
||||||
// Test binding with a different context
|
// Test binding with a different context
|
||||||
clicked = 0;
|
clicked = 0;
|
||||||
jQuery( "#qunit-fixture" ).on( "click", "#foo", function() { clicked++; } );
|
jQuery( "#qunit-fixture" ).on( "click", "#foo", function() {
|
||||||
|
clicked++;
|
||||||
|
} );
|
||||||
jQuery( "#qunit-fixture div" ).trigger( "click" );
|
jQuery( "#qunit-fixture div" ).trigger( "click" );
|
||||||
jQuery( "#foo" ).trigger( "click" );
|
jQuery( "#foo" ).trigger( "click" );
|
||||||
jQuery( "#qunit-fixture" ).trigger( "click" );
|
jQuery( "#qunit-fixture" ).trigger( "click" );
|
||||||
@ -1635,14 +1671,18 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
jQuery( "#body" ).off( "click", "#foo" );
|
jQuery( "#body" ).off( "click", "#foo" );
|
||||||
|
|
||||||
// Verify that return false prevents default action
|
// Verify that return false prevents default action
|
||||||
jQuery( "#body" ).on( "click", "#anchor2", function() { return false; } );
|
jQuery( "#body" ).on( "click", "#anchor2", function() {
|
||||||
|
return false;
|
||||||
|
} );
|
||||||
hash = window.location.hash;
|
hash = window.location.hash;
|
||||||
jQuery( "#anchor2" ).trigger( "click" );
|
jQuery( "#anchor2" ).trigger( "click" );
|
||||||
assert.equal( window.location.hash, hash, "return false worked" );
|
assert.equal( window.location.hash, hash, "return false worked" );
|
||||||
jQuery( "#body" ).off( "click", "#anchor2" );
|
jQuery( "#body" ).off( "click", "#anchor2" );
|
||||||
|
|
||||||
// Verify that .preventDefault() prevents default action
|
// Verify that .preventDefault() prevents default action
|
||||||
jQuery( "#body" ).on( "click", "#anchor2", function( e ) { e.preventDefault(); } );
|
jQuery( "#body" ).on( "click", "#anchor2", function( e ) {
|
||||||
|
e.preventDefault();
|
||||||
|
} );
|
||||||
hash = window.location.hash;
|
hash = window.location.hash;
|
||||||
jQuery( "#anchor2" ).trigger( "click" );
|
jQuery( "#anchor2" ).trigger( "click" );
|
||||||
assert.equal( window.location.hash, hash, "e.preventDefault() worked" );
|
assert.equal( window.location.hash, hash, "e.preventDefault() worked" );
|
||||||
@ -1650,7 +1690,9 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
|
|
||||||
// Test binding the same handler to multiple points
|
// Test binding the same handler to multiple points
|
||||||
called = 0;
|
called = 0;
|
||||||
function callback() { called++; return false; }
|
function callback() {
|
||||||
|
called++; return false;
|
||||||
|
}
|
||||||
|
|
||||||
jQuery( "#body" ).on( "click", "#nothiddendiv", callback );
|
jQuery( "#body" ).on( "click", "#nothiddendiv", callback );
|
||||||
jQuery( "#body" ).on( "click", "#anchor2", callback );
|
jQuery( "#body" ).on( "click", "#anchor2", callback );
|
||||||
@ -1696,8 +1738,14 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
livec = 0;
|
livec = 0;
|
||||||
jQuery( "#nothiddendivchild" ).html( "<span></span>" );
|
jQuery( "#nothiddendivchild" ).html( "<span></span>" );
|
||||||
|
|
||||||
jQuery( "#body" ).on( "click", "#nothiddendivchild", function() { jQuery( "#nothiddendivchild" ).html( "" ); } );
|
jQuery( "#body" ).on( "click", "#nothiddendivchild", function() {
|
||||||
jQuery( "#body" ).on( "click", "#nothiddendivchild", function( e ) { if ( e.target ) {livec++;} } );
|
jQuery( "#nothiddendivchild" ).html( "" );
|
||||||
|
} );
|
||||||
|
jQuery( "#body" ).on( "click", "#nothiddendivchild", function( e ) {
|
||||||
|
if ( e.target ) {
|
||||||
|
livec++;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery( "#nothiddendiv span" ).trigger( "click" );
|
jQuery( "#nothiddendiv span" ).trigger( "click" );
|
||||||
assert.equal( jQuery( "#nothiddendiv span" ).length, 0, "Verify that first handler occurred and modified the DOM." );
|
assert.equal( jQuery( "#nothiddendiv span" ).length, 0, "Verify that first handler occurred and modified the DOM." );
|
||||||
@ -1712,16 +1760,24 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
livee = 0;
|
livee = 0;
|
||||||
|
|
||||||
// bind one pair in one order
|
// bind one pair in one order
|
||||||
jQuery( "#body" ).on( "click", "span#liveSpan1 a", function() { lived++; return false; } );
|
jQuery( "#body" ).on( "click", "span#liveSpan1 a", function() {
|
||||||
jQuery( "#body" ).on( "click", "span#liveSpan1", function() { livee++; } );
|
lived++; return false;
|
||||||
|
} );
|
||||||
|
jQuery( "#body" ).on( "click", "span#liveSpan1", function() {
|
||||||
|
livee++;
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery( "span#liveSpan1 a" ).trigger( "click" );
|
jQuery( "span#liveSpan1 a" ).trigger( "click" );
|
||||||
assert.equal( lived, 1, "Verify that only one first handler occurred." );
|
assert.equal( lived, 1, "Verify that only one first handler occurred." );
|
||||||
assert.equal( livee, 0, "Verify that second handler doesn't." );
|
assert.equal( livee, 0, "Verify that second handler doesn't." );
|
||||||
|
|
||||||
// and one pair in inverse
|
// and one pair in inverse
|
||||||
jQuery( "#body" ).on( "click", "span#liveSpan2", function() { livee++; } );
|
jQuery( "#body" ).on( "click", "span#liveSpan2", function() {
|
||||||
jQuery( "#body" ).on( "click", "span#liveSpan2 a", function() { lived++; return false; } );
|
livee++;
|
||||||
|
} );
|
||||||
|
jQuery( "#body" ).on( "click", "span#liveSpan2 a", function() {
|
||||||
|
lived++; return false;
|
||||||
|
} );
|
||||||
|
|
||||||
lived = 0;
|
lived = 0;
|
||||||
livee = 0;
|
livee = 0;
|
||||||
@ -1747,11 +1803,17 @@ QUnit.test( ".on()/.off()", function( assert ) {
|
|||||||
// Work with deep selectors
|
// Work with deep selectors
|
||||||
livee = 0;
|
livee = 0;
|
||||||
|
|
||||||
function clickB() { livee++; }
|
function clickB() {
|
||||||
|
livee++;
|
||||||
|
}
|
||||||
|
|
||||||
jQuery( "#body" ).on( "click", "#nothiddendiv div", function() { livee++; } );
|
jQuery( "#body" ).on( "click", "#nothiddendiv div", function() {
|
||||||
|
livee++;
|
||||||
|
} );
|
||||||
jQuery( "#body" ).on( "click", "#nothiddendiv div", clickB );
|
jQuery( "#body" ).on( "click", "#nothiddendiv div", clickB );
|
||||||
jQuery( "#body" ).on( "mouseover", "#nothiddendiv div", function() { livee++; } );
|
jQuery( "#body" ).on( "mouseover", "#nothiddendiv div", function() {
|
||||||
|
livee++;
|
||||||
|
} );
|
||||||
|
|
||||||
assert.equal( livee, 0, "No clicks, deep selector." );
|
assert.equal( livee, 0, "No clicks, deep selector." );
|
||||||
|
|
||||||
@ -1825,6 +1887,7 @@ QUnit.test( "events with type matching an Object.prototype property, cloned elem
|
|||||||
elem.appendTo( "#qunit-fixture" );
|
elem.appendTo( "#qunit-fixture" );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Make sure the original element has some event data.
|
// Make sure the original element has some event data.
|
||||||
elem.on( "click", function() {} );
|
elem.on( "click", function() {} );
|
||||||
|
|
||||||
@ -1859,6 +1922,7 @@ QUnit[ QUnit.jQuerySelectors ? "test" : "skip" ]( "delegated event with delegate
|
|||||||
.off( "click" );
|
.off( "click" );
|
||||||
|
|
||||||
if ( QUnit.jQuerySelectorsPos ) {
|
if ( QUnit.jQuerySelectorsPos ) {
|
||||||
|
|
||||||
// Positional selector (trac-11315)
|
// Positional selector (trac-11315)
|
||||||
markup.find( "ul" ).eq( 0 )
|
markup.find( "ul" ).eq( 0 )
|
||||||
.on( "click", ">li>a", function() {
|
.on( "click", ">li>a", function() {
|
||||||
@ -1954,8 +2018,12 @@ QUnit.test( "off all bound delegated events", function( assert ) {
|
|||||||
clicks = 0,
|
clicks = 0,
|
||||||
div = jQuery( "#body" );
|
div = jQuery( "#body" );
|
||||||
|
|
||||||
div.on( "click submit", "div#nothiddendivchild", function() { count++; } );
|
div.on( "click submit", "div#nothiddendivchild", function() {
|
||||||
div.on( "click", function() { clicks++; } );
|
count++;
|
||||||
|
} );
|
||||||
|
div.on( "click", function() {
|
||||||
|
clicks++;
|
||||||
|
} );
|
||||||
div.off( undefined, "**" );
|
div.off( undefined, "**" );
|
||||||
|
|
||||||
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
||||||
@ -1974,7 +2042,9 @@ QUnit.test( "on with multiple delegated events", function( assert ) {
|
|||||||
var count = 0,
|
var count = 0,
|
||||||
div = jQuery( "#body" );
|
div = jQuery( "#body" );
|
||||||
|
|
||||||
div.on( "click submit", "div#nothiddendivchild", function() { count++; } );
|
div.on( "click submit", "div#nothiddendivchild", function() {
|
||||||
|
count++;
|
||||||
|
} );
|
||||||
|
|
||||||
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
jQuery( "div#nothiddendivchild" ).trigger( "click" );
|
||||||
jQuery( "div#nothiddendivchild" ).trigger( "submit" );
|
jQuery( "div#nothiddendivchild" ).trigger( "submit" );
|
||||||
@ -2329,7 +2399,7 @@ QUnit.test( ".on and .off", function( assert ) {
|
|||||||
|
|
||||||
// We should have removed all the event handlers ... kinda hacky way to check this
|
// We should have removed all the event handlers ... kinda hacky way to check this
|
||||||
data = jQuery.data[ jQuery( "#onandoff" )[ 0 ].expando ] || {};
|
data = jQuery.data[ jQuery( "#onandoff" )[ 0 ].expando ] || {};
|
||||||
assert.equal( data[ "events" ], undefined, "no events left" );
|
assert.equal( data.events, undefined, "no events left" );
|
||||||
|
|
||||||
$onandoff.remove();
|
$onandoff.remove();
|
||||||
} );
|
} );
|
||||||
@ -2403,7 +2473,7 @@ QUnit.test( "special on name mapping", function( assert ) {
|
|||||||
.trigger( "gutfeeling" ) // This one should not
|
.trigger( "gutfeeling" ) // This one should not
|
||||||
.remove();
|
.remove();
|
||||||
|
|
||||||
delete jQuery.event.special[ "gutfeeling" ];
|
delete jQuery.event.special.gutfeeling;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( ".on and .off, selective mixed removal (trac-10705)", function( assert ) {
|
QUnit.test( ".on and .off, selective mixed removal (trac-10705)", function( assert ) {
|
||||||
@ -2544,7 +2614,9 @@ QUnit.test( "addProp extensions", function( assert ) {
|
|||||||
fireNative( $fixture[ 0 ], "click" );
|
fireNative( $fixture[ 0 ], "click" );
|
||||||
$fixture.off( "click" );
|
$fixture.off( "click" );
|
||||||
|
|
||||||
jQuery.event.addProp( "testProperty", function() { return 42; } );
|
jQuery.event.addProp( "testProperty", function() {
|
||||||
|
return 42;
|
||||||
|
} );
|
||||||
|
|
||||||
// Trigger a native click and ensure the property is set
|
// Trigger a native click and ensure the property is set
|
||||||
$fixture.on( "click", function( event ) {
|
$fixture.on( "click", function( event ) {
|
||||||
@ -3362,6 +3434,7 @@ QUnit.test( "focus change during a focus handler (gh-4382)", function( assert )
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
jQuery( document ).on( "focusin.focusTests", function( ev ) {
|
jQuery( document ).on( "focusin.focusTests", function( ev ) {
|
||||||
|
|
||||||
// Support: IE 11+
|
// Support: IE 11+
|
||||||
// In IE focus is async so focusin on document is fired multiple times,
|
// In IE focus is async so focusin on document is fired multiple times,
|
||||||
// for each of the elements. In other browsers it's fired just once, for
|
// for each of the elements. In other browsers it's fired just once, for
|
||||||
|
@ -518,6 +518,7 @@ QUnit.test( "Tag name processing respects the HTML Standard (gh-2005)", function
|
|||||||
}
|
}
|
||||||
|
|
||||||
function assertSpecialCharsSupport( method, characters ) {
|
function assertSpecialCharsSupport( method, characters ) {
|
||||||
|
|
||||||
// Support: Android 4.4 only
|
// Support: Android 4.4 only
|
||||||
// Chromium < 35 incorrectly upper-cases µ; Android 4.4 uses such a version by default
|
// 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
|
// (and its WebView, being un-updatable, will use it for eternity) so we need to blacklist
|
||||||
@ -1364,9 +1365,13 @@ QUnit.test( "Empty replaceWith (trac-13401; trac-13596; gh-2204)", function( ass
|
|||||||
jQuery.each( tests, function( label, input ) {
|
jQuery.each( tests, function( label, input ) {
|
||||||
$el.html( "<a></a>" ).children().replaceWith( input );
|
$el.html( "<a></a>" ).children().replaceWith( input );
|
||||||
assert.strictEqual( $el.html(), "", "replaceWith(" + label + ")" );
|
assert.strictEqual( $el.html(), "", "replaceWith(" + label + ")" );
|
||||||
$el.html( "<b></b>" ).children().replaceWith( function() { return input; } );
|
$el.html( "<b></b>" ).children().replaceWith( function() {
|
||||||
|
return input;
|
||||||
|
} );
|
||||||
assert.strictEqual( $el.html(), "", "replaceWith(function returning " + label + ")" );
|
assert.strictEqual( $el.html(), "", "replaceWith(function returning " + label + ")" );
|
||||||
$el.html( "<i></i>" ).children().replaceWith( function( i ) { return input; } );
|
$el.html( "<i></i>" ).children().replaceWith( function( i ) {
|
||||||
|
return input;
|
||||||
|
} );
|
||||||
assert.strictEqual( $el.html(), "", "replaceWith(other function returning " + label + ")" );
|
assert.strictEqual( $el.html(), "", "replaceWith(other function returning " + label + ")" );
|
||||||
$el.html( "<p></p>" ).children().replaceWith( function( i ) {
|
$el.html( "<p></p>" ).children().replaceWith( function( i ) {
|
||||||
return i ?
|
return i ?
|
||||||
@ -1606,7 +1611,9 @@ QUnit.test( "clone(form element) (Bug trac-3879, trac-6655)", function( assert )
|
|||||||
|
|
||||||
element = jQuery( "<select><option>Foo</option><option value='selected' selected>Bar</option></select>" );
|
element = jQuery( "<select><option>Foo</option><option value='selected' selected>Bar</option></select>" );
|
||||||
|
|
||||||
assert.equal( element.clone().find( "option" ).filter( function() { return this.selected; } ).val(), "selected", "Selected option cloned correctly" );
|
assert.equal( element.clone().find( "option" ).filter( function() {
|
||||||
|
return this.selected;
|
||||||
|
} ).val(), "selected", "Selected option cloned correctly" );
|
||||||
|
|
||||||
element = jQuery( "<input type='checkbox' value='foo'>" ).attr( "checked", "checked" );
|
element = jQuery( "<input type='checkbox' value='foo'>" ).attr( "checked", "checked" );
|
||||||
clone = element.clone();
|
clone = element.clone();
|
||||||
@ -1805,6 +1812,7 @@ QUnit.test( "html(Function)", function( assert ) {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit[
|
QUnit[
|
||||||
|
|
||||||
// Support: Edge 16-18+
|
// Support: Edge 16-18+
|
||||||
// Edge sometimes doesn't execute module scripts so skip the test there.
|
// Edge sometimes doesn't execute module scripts so skip the test there.
|
||||||
( QUnit.moduleTypeSupported && !/edge\//i.test( navigator.userAgent ) ) ?
|
( QUnit.moduleTypeSupported && !/edge\//i.test( navigator.userAgent ) ) ?
|
||||||
@ -1833,6 +1841,7 @@ QUnit[
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit[
|
QUnit[
|
||||||
|
|
||||||
// Support: IE 9-11 only, Android 4.0-4.4 only, iOS 7-10 only
|
// Support: IE 9-11 only, Android 4.0-4.4 only, iOS 7-10 only
|
||||||
// `nomodule` scripts should be executed by legacy browsers only.
|
// `nomodule` scripts should be executed by legacy browsers only.
|
||||||
// iOS 10 supports `<script type="module">` but doesn't support the nomodule attribute
|
// iOS 10 supports `<script type="module">` but doesn't support the nomodule attribute
|
||||||
@ -2266,8 +2275,7 @@ QUnit.test( "domManip plain-text caching (trac-6779)", function( assert ) {
|
|||||||
for ( i = 0; i < bad.length; i++ ) {
|
for ( i = 0; i < bad.length; i++ ) {
|
||||||
try {
|
try {
|
||||||
$f.append( bad[ i ] );
|
$f.append( bad[ i ] );
|
||||||
}
|
} catch ( e ) {}
|
||||||
catch ( e ) {}
|
|
||||||
}
|
}
|
||||||
assert.equal( $f.text(), bad.join( "" ), "Cached strings that match Object properties" );
|
assert.equal( $f.text(), bad.join( "" ), "Cached strings that match Object properties" );
|
||||||
$f.remove();
|
$f.remove();
|
||||||
|
@ -622,6 +622,7 @@ QUnit.test( "chaining", function( assert ) {
|
|||||||
// parent is not offsetParent); offset includes parent offset+border+padding
|
// parent is not offsetParent); offset includes parent offset+border+padding
|
||||||
// static: same as relative
|
// static: same as relative
|
||||||
for ( ; parent; parent = expectations[ parent.parent ] ) {
|
for ( ; parent; parent = expectations[ parent.parent ] ) {
|
||||||
|
|
||||||
// position:fixed
|
// position:fixed
|
||||||
if ( props.style === "fixed" ) {
|
if ( props.style === "fixed" ) {
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +88,9 @@ QUnit.test( "queue() passes in the next item in the queue as a parameter to fx q
|
|||||||
|
|
||||||
div.queue( function( next ) {
|
div.queue( function( next ) {
|
||||||
assert.equal( ++counter, 1, "Dequeueing" );
|
assert.equal( ++counter, 1, "Dequeueing" );
|
||||||
setTimeout( function() { next(); }, 500 );
|
setTimeout( function() {
|
||||||
|
next();
|
||||||
|
}, 500 );
|
||||||
} ).queue( function( next ) {
|
} ).queue( function( next ) {
|
||||||
assert.equal( ++counter, 2, "Next was called" );
|
assert.equal( ++counter, 2, "Next was called" );
|
||||||
next();
|
next();
|
||||||
@ -187,7 +189,9 @@ QUnit.test( "clearQueue() clears the fx queue", function( assert ) {
|
|||||||
div.queue( function( next ) {
|
div.queue( function( next ) {
|
||||||
counter++;
|
counter++;
|
||||||
var self = this;
|
var self = this;
|
||||||
setTimeout( function() { jQuery( self ).clearQueue(); next(); }, 50 );
|
setTimeout( function() {
|
||||||
|
jQuery( self ).clearQueue(); next();
|
||||||
|
}, 50 );
|
||||||
} ).queue( function() {
|
} ).queue( function() {
|
||||||
counter++;
|
counter++;
|
||||||
} );
|
} );
|
||||||
|
@ -41,8 +41,8 @@ QUnit.test( "empty", function( assert ) {
|
|||||||
QUnit.test( "star", function( assert ) {
|
QUnit.test( "star", function( assert ) {
|
||||||
assert.expect( 2 );
|
assert.expect( 2 );
|
||||||
|
|
||||||
var good, i;
|
var good, i,
|
||||||
var all = jQuery.find( "*" );
|
all = jQuery.find( "*" );
|
||||||
|
|
||||||
assert.ok( all.length >= 30, "Select all" );
|
assert.ok( all.length >= 30, "Select all" );
|
||||||
good = true;
|
good = true;
|
||||||
@ -57,8 +57,8 @@ QUnit.test( "star", function( assert ) {
|
|||||||
QUnit.test( "element", function( assert ) {
|
QUnit.test( "element", function( assert ) {
|
||||||
assert.expect( 37 );
|
assert.expect( 37 );
|
||||||
|
|
||||||
var i, lengthtest, siblingTest, html;
|
var i, lengthtest, siblingTest, html,
|
||||||
var fixture = document.getElementById( "qunit-fixture" );
|
fixture = document.getElementById( "qunit-fixture" );
|
||||||
|
|
||||||
assert.deepEqual( jQuery( "p", fixture ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a Node context." );
|
assert.deepEqual( jQuery( "p", fixture ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a Node context." );
|
||||||
assert.deepEqual( jQuery( "p", "#qunit-fixture" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a selector context." );
|
assert.deepEqual( jQuery( "p", "#qunit-fixture" ).get(), q( "firstp", "ap", "sndp", "en", "sap", "first" ), "Finding elements with a selector context." );
|
||||||
@ -892,6 +892,7 @@ QUnit.test( "pseudo - nth-child", function( assert ) {
|
|||||||
"Seeded nth-child"
|
"Seeded nth-child"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support: Chrome 75+, Firefox 67+
|
// Support: Chrome 75+, Firefox 67+
|
||||||
// Some browsers mark disconnected elements as matching `:nth-child(n)`
|
// Some browsers mark disconnected elements as matching `:nth-child(n)`
|
||||||
// so let's skip the test.
|
// so let's skip the test.
|
||||||
@ -948,6 +949,7 @@ QUnit.test( "pseudo - nth-last-child", function( assert ) {
|
|||||||
"Seeded nth-last-child"
|
"Seeded nth-last-child"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support: Chrome 75+, Firefox 67+
|
// Support: Chrome 75+, Firefox 67+
|
||||||
// Some browsers mark disconnected elements as matching `:nth-last-child(n)`
|
// Some browsers mark disconnected elements as matching `:nth-last-child(n)`
|
||||||
// so let's skip the test.
|
// so let's skip the test.
|
||||||
@ -1084,6 +1086,7 @@ QUnit.test( "pseudo - misc", function( assert ) {
|
|||||||
tmp = document.createElement( "div" );
|
tmp = document.createElement( "div" );
|
||||||
tmp.id = "tmp_input";
|
tmp.id = "tmp_input";
|
||||||
tmp.innerHTML = "<span>Hello I am focusable.</span>";
|
tmp.innerHTML = "<span>Hello I am focusable.</span>";
|
||||||
|
|
||||||
// Setting tabIndex should make the element focusable
|
// Setting tabIndex should make the element focusable
|
||||||
// http://dev.w3.org/html5/spec/single-page.html#focus-management
|
// http://dev.w3.org/html5/spec/single-page.html#focus-management
|
||||||
document.body.appendChild( tmp );
|
document.body.appendChild( tmp );
|
||||||
@ -1140,6 +1143,7 @@ QUnit.test( "pseudo - misc", function( assert ) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( QUnit.jQuerySelectors ) {
|
if ( QUnit.jQuerySelectors ) {
|
||||||
|
|
||||||
// Tokenization edge cases
|
// Tokenization edge cases
|
||||||
assert.t( "Sequential pseudos", "#qunit-fixture p:has(:contains(mark)):has(code)", [ "ap" ] );
|
assert.t( "Sequential pseudos", "#qunit-fixture p:has(:contains(mark)):has(code)", [ "ap" ] );
|
||||||
assert.t( "Sequential pseudos", "#qunit-fixture p:has(:contains(mark)):has(code):contains(This link)", [ "ap" ] );
|
assert.t( "Sequential pseudos", "#qunit-fixture p:has(:contains(mark)):has(code):contains(This link)", [ "ap" ] );
|
||||||
@ -1205,6 +1209,7 @@ QUnit.test( "pseudo - :not", function( assert ) {
|
|||||||
assert.t( ":not() failing interior", "#qunit-fixture p:not(div#blargh)", [ "firstp", "ap", "sndp", "en", "sap", "first" ] );
|
assert.t( ":not() failing interior", "#qunit-fixture p:not(div#blargh)", [ "firstp", "ap", "sndp", "en", "sap", "first" ] );
|
||||||
assert.t( ":not() failing interior", "#qunit-fixture p:not(p#blargh)", [ "firstp", "ap", "sndp", "en", "sap", "first" ] );
|
assert.t( ":not() failing interior", "#qunit-fixture p:not(p#blargh)", [ "firstp", "ap", "sndp", "en", "sap", "first" ] );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support: Chrome 75+, Firefox 67+
|
// Support: Chrome 75+, Firefox 67+
|
||||||
// Chrome/Firefox don't support `:not(complex selector)`.
|
// Chrome/Firefox don't support `:not(complex selector)`.
|
||||||
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
||||||
@ -1225,6 +1230,7 @@ QUnit.test( "pseudo - :not", function( assert ) {
|
|||||||
assert.t( ":not Multiple", "p:not(p,a)", [] );
|
assert.t( ":not Multiple", "p:not(p,a)", [] );
|
||||||
assert.t( ":not Multiple", "p:not(a,p,b)", [] );
|
assert.t( ":not Multiple", "p:not(a,p,b)", [] );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support: Chrome 75+, Firefox 67+
|
// Support: Chrome 75+, Firefox 67+
|
||||||
// Chrome/Firefox don't support `:not(complex selector)`.
|
// Chrome/Firefox don't support `:not(complex selector)`.
|
||||||
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
||||||
@ -1254,6 +1260,7 @@ QUnit.test( "pseudo - :not", function( assert ) {
|
|||||||
if ( QUnit.jQuerySelectors || this.safari ) {
|
if ( QUnit.jQuerySelectors || this.safari ) {
|
||||||
assert.t( ":not() Multiple Class", "#foo a:not(.blog.link)", [ "yahoo", "anchor2" ] );
|
assert.t( ":not() Multiple Class", "#foo a:not(.blog.link)", [ "yahoo", "anchor2" ] );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support: Chrome 75+, Firefox 67+
|
// Support: Chrome 75+, Firefox 67+
|
||||||
// Chrome/Firefox don't support `:not(complex selector)`.
|
// Chrome/Firefox don't support `:not(complex selector)`.
|
||||||
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
assert.ok( "skip", ":not(complex selector) not supported in selector-native" );
|
||||||
@ -1830,8 +1837,8 @@ QUnit[
|
|||||||
"Shadow DOM nodes supported as root", function( assert ) {
|
"Shadow DOM nodes supported as root", function( assert ) {
|
||||||
assert.expect( 2 );
|
assert.expect( 2 );
|
||||||
|
|
||||||
var shadowHost = jQuery( "<div/>" ).appendTo( "#qunit-fixture" )[ 0 ];
|
var shadowHost = jQuery( "<div/>" ).appendTo( "#qunit-fixture" )[ 0 ],
|
||||||
var shadowRoot = shadowHost.attachShadow( { mode: "open" } );
|
shadowRoot = shadowHost.attachShadow( { mode: "open" } );
|
||||||
|
|
||||||
shadowRoot.innerHTML = "<div class='vagabond'><p></p></div>";
|
shadowRoot.innerHTML = "<div class='vagabond'><p></p></div>";
|
||||||
assert.equal( jQuery( shadowRoot ).find( ".vagabond" ).length, 1,
|
assert.equal( jQuery( shadowRoot ).find( ".vagabond" ).length, 1,
|
||||||
@ -1843,7 +1850,7 @@ QUnit[
|
|||||||
testIframe(
|
testIframe(
|
||||||
"attributes - jQuery.attr",
|
"attributes - jQuery.attr",
|
||||||
"selector/html5_selector.html",
|
"selector/html5_selector.html",
|
||||||
function( assert, jQuery, window, document ) {
|
function( assert, jQuery, _window, document ) {
|
||||||
assert.expect( 38 );
|
assert.expect( 38 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1916,7 +1923,7 @@ testIframe(
|
|||||||
|
|
||||||
// Enumerated attributes (these are not boolean content attributes)
|
// Enumerated attributes (these are not boolean content attributes)
|
||||||
jQuery.expandedEach = jQuery.each;
|
jQuery.expandedEach = jQuery.each;
|
||||||
jQuery.expandedEach( [ "draggable", "contenteditable", "aria-disabled" ], function( i, val ) {
|
jQuery.expandedEach( [ "draggable", "contenteditable", "aria-disabled" ], function( _i, val ) {
|
||||||
t( "Enumerated attribute", "[" + val + "]", [ "div1" ] );
|
t( "Enumerated attribute", "[" + val + "]", [ "div1" ] );
|
||||||
} );
|
} );
|
||||||
t( "Enumerated attribute", "[spellcheck]", [ "span1" ] );
|
t( "Enumerated attribute", "[spellcheck]", [ "span1" ] );
|
||||||
@ -2123,7 +2130,7 @@ QUnit.test( "uniqueSort()", function( assert ) {
|
|||||||
testIframe(
|
testIframe(
|
||||||
"jQuery.uniqueSort works cross-window (trac-14381)",
|
"jQuery.uniqueSort works cross-window (trac-14381)",
|
||||||
"selector/mixed_sort.html",
|
"selector/mixed_sort.html",
|
||||||
function( assert, jQuery, window, document, actual, expected ) {
|
function( assert, _jQuery, _window, _document, actual, expected ) {
|
||||||
assert.expect( 1 );
|
assert.expect( 1 );
|
||||||
|
|
||||||
assert.deepEqual( actual, expected, "Mixed array was sorted correctly" );
|
assert.deepEqual( actual, expected, "Mixed array was sorted correctly" );
|
||||||
@ -2292,10 +2299,12 @@ function testAttr( doc, assert ) {
|
|||||||
|
|
||||||
var el;
|
var el;
|
||||||
if ( doc ) {
|
if ( doc ) {
|
||||||
|
|
||||||
// XML
|
// XML
|
||||||
el = doc.createElement( "input" );
|
el = doc.createElement( "input" );
|
||||||
el.setAttribute( "type", "checkbox" );
|
el.setAttribute( "type", "checkbox" );
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Set checked on creation by creating with a fragment
|
// Set checked on creation by creating with a fragment
|
||||||
// See https://jsfiddle.net/8sVgA/1/show/light in oldIE
|
// See https://jsfiddle.net/8sVgA/1/show/light in oldIE
|
||||||
el = jQuery( "<input type='checkbox' checked='checked' />" )[ 0 ];
|
el = jQuery( "<input type='checkbox' checked='checked' />" )[ 0 ];
|
||||||
@ -2423,6 +2432,7 @@ QUnit[ QUnit.jQuerySelectors ? "test" : "skip" ]( "backwards-compatible custom p
|
|||||||
var count = argument == null || argument === "" ? 3 : +argument;
|
var count = argument == null || argument === "" ? 3 : +argument;
|
||||||
return elements.slice( 0, count );
|
return elements.slice( 0, count );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Using TAG as the first token here forces this setMatcher into a fail state
|
// Using TAG as the first token here forces this setMatcher into a fail state
|
||||||
// Where the descendent combinator was lost
|
// Where the descendent combinator was lost
|
||||||
assert.t( "Custom setFilter", "form#form :PODIUM", [ "label-for", "text1", "text2" ] );
|
assert.t( "Custom setFilter", "form#form :PODIUM", [ "label-for", "text1", "text2" ] );
|
||||||
@ -2550,7 +2560,7 @@ QUnit[ QUnit.jQuerySelectors ? "test" : "skip" ]( "jQuery.find.select with pre-c
|
|||||||
"#qunit-fixture #first",
|
"#qunit-fixture #first",
|
||||||
"ol#listWithTabIndex > li[tabindex]",
|
"ol#listWithTabIndex > li[tabindex]",
|
||||||
"#liveSpan1"
|
"#liveSpan1"
|
||||||
], function( i, selector ) {
|
], function( _i, selector ) {
|
||||||
var compiled = jQuery.find.compile( selector );
|
var compiled = jQuery.find.compile( selector );
|
||||||
assert.equal( jQuery.find.select( compiled, document ).length,
|
assert.equal( jQuery.find.select( compiled, document ).length,
|
||||||
1, "Should match using a compiled selector function" );
|
1, "Should match using a compiled selector function" );
|
||||||
|
@ -64,7 +64,9 @@ QUnit.test( "jQuery.param()", function( assert ) {
|
|||||||
params = { "param1": null };
|
params = { "param1": null };
|
||||||
assert.equal( jQuery.param( params ), "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; } };
|
params = { "param1": function() {}, "param2": function() {
|
||||||
|
return null;
|
||||||
|
} };
|
||||||
assert.equal( jQuery.param( params, false ), "param1=¶m2=", "object with function property that returns null value" );
|
assert.equal( jQuery.param( params, false ), "param1=¶m2=", "object with function property that returns null value" );
|
||||||
|
|
||||||
params = { "test": { "length": 3, "foo": "bar" } };
|
params = { "test": { "length": 3, "foo": "bar" } };
|
||||||
|
@ -310,7 +310,9 @@ QUnit.test( "filter(Function)", function( assert ) {
|
|||||||
return !jQuery( "a", this ).length;
|
return !jQuery( "a", this ).length;
|
||||||
} ).get(), q( "sndp", "first" ), "filter(Function)" );
|
} ).get(), q( "sndp", "first" ), "filter(Function)" );
|
||||||
|
|
||||||
assert.deepEqual( jQuery( "#qunit-fixture p" ).filter( function( i, elem ) { return !jQuery( "a", elem ).length; } ).get(), q( "sndp", "first" ), "filter(Function) using arg" );
|
assert.deepEqual( jQuery( "#qunit-fixture p" ).filter( function( i, elem ) {
|
||||||
|
return !jQuery( "a", elem ).length;
|
||||||
|
} ).get(), q( "sndp", "first" ), "filter(Function) using arg" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( "filter(Element)", function( assert ) {
|
QUnit.test( "filter(Element)", function( assert ) {
|
||||||
@ -505,7 +507,9 @@ QUnit.test( "not(Element)", function( assert ) {
|
|||||||
QUnit.test( "not(Function)", function( assert ) {
|
QUnit.test( "not(Function)", function( assert ) {
|
||||||
assert.expect( 1 );
|
assert.expect( 1 );
|
||||||
|
|
||||||
assert.deepEqual( jQuery( "#qunit-fixture p" ).not( function() { return jQuery( "a", this ).length; } ).get(), q( "sndp", "first" ), "not(Function)" );
|
assert.deepEqual( jQuery( "#qunit-fixture p" ).not( function() {
|
||||||
|
return jQuery( "a", this ).length;
|
||||||
|
} ).get(), q( "sndp", "first" ), "not(Function)" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( "not(Array)", function( assert ) {
|
QUnit.test( "not(Array)", function( assert ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user