From 496b142e5db0a27a4d4475894174b331faedae29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82e=CC=A8biowski-Owczarek?= Date: Mon, 8 Apr 2019 20:18:55 +0200 Subject: [PATCH] Core: Drop support for IE <11, iOS <10, Android Browser & PhantomJS Also, update support comments format to match format described in: https://github.com/jquery/contribute.jquery.org/issues/95#issuecomment-69379197 with the change from: https://github.com/jquery/contribute.jquery.org/issues/95#issuecomment-448998379 (open-ended ranges end with `+`). Further size reductions will be achieved when we drop Firefox 60, iOS 10 and pre-Chromium Edge versions. Fixes gh-3950 Fixes gh-4299 --- .eslintrc-browser.json | 5 +- .travis.yml | 1 - Gruntfile.js | 43 +--- src/ajax.js | 9 +- src/ajax/jsonp.js | 7 +- src/ajax/load.js | 5 +- src/ajax/xhr.js | 218 ++++++++------------ src/attributes/classes.js | 9 +- src/attributes/prop.js | 6 +- src/attributes/support.js | 4 - src/attributes/val.js | 14 +- src/callbacks.js | 5 +- src/core.js | 27 +-- src/core/DOMEval.js | 2 +- src/core/access.js | 7 +- src/core/camelCase.js | 2 +- src/core/init.js | 7 +- src/core/parseHTML.js | 27 +-- src/core/ready-no-deferred.js | 12 +- src/core/ready.js | 5 +- src/core/support.js | 20 -- src/core/toType.js | 3 +- src/css.js | 40 +--- src/css/adjustCSS.js | 2 +- src/css/curCSS.js | 7 +- src/css/support.js | 17 +- src/css/var/getStyles.js | 13 +- src/css/var/isHiddenWithinTree.js | 2 +- src/data/Data.js | 2 +- src/deferred.js | 29 ++- src/deferred/exceptionHook.js | 10 +- src/deprecated.js | 10 +- src/effects.js | 22 +- src/effects/Tween.js | 10 - src/event.js | 51 ++--- src/event/focusin.js | 6 +- src/event/trigger.js | 5 +- src/manipulation.js | 46 ++--- src/manipulation/buildFragment.js | 5 - src/manipulation/support.js | 7 - src/offset.js | 8 +- src/selector-native.js | 6 +- src/serialize.js | 5 +- src/traversing.js | 2 +- src/traversing/findFilter.js | 5 +- src/var/isFunction.js | 13 -- src/var/trim.js | 5 + src/wrap.js | 9 +- src/wrapper.js | 4 - test/data/core/cc_on.html | 23 --- test/data/testinit.js | 46 +---- test/data/testrunner.js | 2 + test/unit/ajax.js | 102 ++++------ test/unit/basic.js | 6 +- test/unit/core.js | 26 +-- test/unit/css.js | 69 ++----- test/unit/deferred.js | 73 ++----- test/unit/deprecated.js | 4 +- test/unit/dimensions.js | 34 +--- test/unit/effects.js | 49 ++--- test/unit/event.js | 21 +- test/unit/manipulation.js | 91 +++------ test/unit/offset.js | 98 +++------ test/unit/support.js | 324 ++++++++---------------------- 64 files changed, 513 insertions(+), 1234 deletions(-) delete mode 100644 src/core/support.js delete mode 100644 src/var/isFunction.js create mode 100644 src/var/trim.js delete mode 100644 test/data/core/cc_on.html diff --git a/.eslintrc-browser.json b/.eslintrc-browser.json index ffd5b64674e..146745d0ec2 100644 --- a/.eslintrc-browser.json +++ b/.eslintrc-browser.json @@ -3,11 +3,8 @@ "extends": "jquery", - // 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 + "ecmaVersion": 5 }, // The browser env is not enabled on purpose so that code takes diff --git a/.travis.yml b/.travis.yml index 01111e1102c..6e46896b00b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: node_js sudo: false node_js: -- "6" - "8" - "10" - "11" diff --git a/Gruntfile.js b/Gruntfile.js index 7fa324399b0..7db56b2603d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,15 +14,7 @@ module.exports = function( grunt ) { var fs = require( "fs" ), gzip = require( "gzip-js" ), - isTravis = process.env.TRAVIS, - oldNode = /^v6\./.test( process.version ); - - // Support: Node.js <8 - // Skip running tasks that dropped support for Node.js 6 - // in those Node versions. - function runIfNewNode( task ) { - return oldNode ? "print_old_node_message:" + task : task; - } + isTravis = process.env.TRAVIS; if ( !grunt.option( "filename" ) ) { grunt.option( "filename", "jquery.js" ); @@ -123,10 +115,9 @@ module.exports = function( grunt ) { testswarm: { tests: [ - // A special module with basic tests, meant for - // not fully supported environments like Android 2.3, - // jsdom or PhantomJS. We run it everywhere, though, - // to make sure tests are not broken. + // A special module with basic tests, meant for not fully + // supported environments like jsdom. We run it everywhere, + // though, to make sure tests are not broken. "basic", "ajax", @@ -291,23 +282,13 @@ module.exports = function( grunt ) { "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 + "ascii_only": true }, banner: "/*! jQuery v<%= pkg.version %> | " + "(c) JS 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 + loops: false } } } @@ -320,13 +301,6 @@ module.exports = function( grunt ) { // Integrate jQuery specific tasks grunt.loadTasks( "build/tasks" ); - // Support: Node.js <8 - // Print a message on Node.js <8 notifying the task is skipped there. - grunt.registerTask( "print_old_node_message", function() { - var task = [].slice.call( arguments ).join( ":" ); - grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." ); - } ); - grunt.registerTask( "lint", [ "jsonlint", @@ -349,10 +323,7 @@ module.exports = function( grunt ) { grunt.registerTask( "test:fast", "node_smoke_tests" ); grunt.registerTask( "test:slow", [ "promises_aplus_tests", - - // Support: Node.js <8 - // Karma no longer supports Node.js <8 as it relies on async-await internally. - runIfNewNode( "karma:jsdom" ) + "karma:jsdom" ] ); grunt.registerTask( "test", [ diff --git a/src/ajax.js b/src/ajax.js index 4cbefabaaf3..6dc11d9801d 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -1,7 +1,6 @@ define( [ "./core", "./var/document", - "./var/isFunction", "./var/rnothtmlwhite", "./ajax/var/location", "./ajax/var/nonce", @@ -12,7 +11,7 @@ define( [ "./event/trigger", "./deferred", "./serialize" // jQuery.param -], function( jQuery, document, isFunction, rnothtmlwhite, location, nonce, rquery ) { +], function( jQuery, document, rnothtmlwhite, location, nonce, rquery ) { "use strict"; @@ -67,7 +66,7 @@ function addToPrefiltersOrTransports( structure ) { i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - if ( isFunction( func ) ) { + if ( typeof func === "function" ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { @@ -541,7 +540,7 @@ jQuery.extend( { if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); - // Support: IE <=8 - 11, Edge 12 - 15 + // Support: IE <=8 - 11 only, Edge 12 - 17 only // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { @@ -837,7 +836,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { + if ( typeof data === "function" ) { type = type || callback; callback = data; data = undefined; diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js index 28ae0365db9..dbdb4dbb870 100644 --- a/src/ajax/jsonp.js +++ b/src/ajax/jsonp.js @@ -1,10 +1,9 @@ define( [ "../core", - "../var/isFunction", "./var/nonce", "./var/rquery", "../ajax" -], function( jQuery, isFunction, nonce, rquery ) { +], function( jQuery, nonce, rquery ) { "use strict"; @@ -37,7 +36,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it - callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? + callbackName = s.jsonpCallback = typeof s.jsonpCallback === "function" ? s.jsonpCallback() : s.jsonpCallback; @@ -88,7 +87,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { } // Call if it was a function and we have a response - if ( responseContainer && isFunction( overwritten ) ) { + if ( responseContainer && typeof overwritten === "function" ) { overwritten( responseContainer[ 0 ] ); } diff --git a/src/ajax/load.js b/src/ajax/load.js index defdb017454..574d6b4a733 100644 --- a/src/ajax/load.js +++ b/src/ajax/load.js @@ -1,13 +1,12 @@ define( [ "../core", "../core/stripAndCollapse", - "../var/isFunction", "../core/parseHTML", "../ajax", "../traversing", "../manipulation", "../selector" -], function( jQuery, stripAndCollapse, isFunction ) { +], function( jQuery, stripAndCollapse ) { "use strict"; @@ -25,7 +24,7 @@ jQuery.fn.load = function( url, params, callback ) { } // If it's a function - if ( isFunction( params ) ) { + if ( typeof params === "function" ) { // We assume that it's the callback callback = params; diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 4a31171aca1..16a2ac3d8a9 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -1,8 +1,7 @@ define( [ "../core", - "../var/support", "../ajax" -], function( jQuery, support ) { +], function( jQuery ) { "use strict"; @@ -15,156 +14,109 @@ jQuery.ajaxSettings.xhr = function() { var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; + 0: 200 + }; jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; + var callback; // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; } + } - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) === "text" ? + { text: xhr.responseText } : + { binary: xhr.response }, + xhr.getAllResponseHeaders() + ); } - }; + } }; + }; - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); + // Listen to events + xhr.onload = callback(); + xhr.onabort = xhr.onerror = xhr.ontimeout = callback( "error" ); - try { + // Create the abort callback + callback = callback( "abort" ); - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { + try { - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { - abort: function() { + // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { - callback(); + throw e; } } - }; - } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; } ); } ); diff --git a/src/attributes/classes.js b/src/attributes/classes.js index 0c90a8dffdb..f1571eb5d06 100644 --- a/src/attributes/classes.js +++ b/src/attributes/classes.js @@ -1,11 +1,10 @@ define( [ "../core", "../core/stripAndCollapse", - "../var/isFunction", "../var/rnothtmlwhite", "../data/var/dataPriv", "../core/init" -], function( jQuery, stripAndCollapse, isFunction, rnothtmlwhite, dataPriv ) { +], function( jQuery, stripAndCollapse, rnothtmlwhite, dataPriv ) { "use strict"; @@ -28,7 +27,7 @@ jQuery.fn.extend( { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; - if ( isFunction( value ) ) { + if ( typeof value === "function" ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); @@ -65,7 +64,7 @@ jQuery.fn.extend( { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; - if ( isFunction( value ) ) { + if ( typeof value === "function" ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); @@ -114,7 +113,7 @@ jQuery.fn.extend( { return stateVal ? this.addClass( value ) : this.removeClass( value ); } - if ( isFunction( value ) ) { + if ( typeof value === "function" ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), diff --git a/src/attributes/prop.js b/src/attributes/prop.js index 49ac244dfdf..6c53bc36e7b 100644 --- a/src/attributes/prop.js +++ b/src/attributes/prop.js @@ -101,23 +101,23 @@ if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { - /* eslint no-unused-expressions: "off" */ - var parent = elem.parentNode; if ( parent && parent.parentNode ) { + // eslint-disable-next-line no-unused-expressions parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { - /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { + // eslint-disable-next-line no-unused-expressions parent.selectedIndex; if ( parent.parentNode ) { + // eslint-disable-next-line no-unused-expressions parent.parentNode.selectedIndex; } } diff --git a/src/attributes/support.js b/src/attributes/support.js index af60e96949b..e8b6b3bd330 100644 --- a/src/attributes/support.js +++ b/src/attributes/support.js @@ -12,10 +12,6 @@ define( [ input.type = "checkbox"; - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; diff --git a/src/attributes/val.js b/src/attributes/val.js index c719b34b398..50dba43ab95 100644 --- a/src/attributes/val.js +++ b/src/attributes/val.js @@ -3,10 +3,9 @@ define( [ "../core/stripAndCollapse", "./support", "../core/nodeName", - "../var/isFunction", "../core/init" -], function( jQuery, stripAndCollapse, support, nodeName, isFunction ) { +], function( jQuery, stripAndCollapse, support, nodeName ) { "use strict"; @@ -43,7 +42,7 @@ jQuery.fn.extend( { return; } - valueIsFunction = isFunction( value ); + valueIsFunction = typeof value === "function"; return this.each( function( i ) { var val; @@ -117,9 +116,7 @@ jQuery.extend( { for ( ; i < max; i++ ) { option = options[ i ]; - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && + if ( option.selected && // Don't return options that are disabled or in a disabled optgroup !option.disabled && @@ -181,11 +178,6 @@ jQuery.each( [ "radio", "checkbox" ], function() { } } }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } } ); } ); diff --git a/src/callbacks.js b/src/callbacks.js index 6cf54031e39..140c4979ea0 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -1,9 +1,8 @@ define( [ "./core", "./core/toType", - "./var/isFunction", "./var/rnothtmlwhite" -], function( jQuery, toType, isFunction, rnothtmlwhite ) { +], function( jQuery, toType, rnothtmlwhite ) { "use strict"; @@ -127,7 +126,7 @@ jQuery.Callbacks = function( options ) { ( function add( args ) { jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { + if ( typeof arg === "function" ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } diff --git a/src/core.js b/src/core.js index 3ef92d48fc2..5a5c7469eb8 100644 --- a/src/core.js +++ b/src/core.js @@ -15,14 +15,14 @@ define( [ "./var/hasOwn", "./var/fnToString", "./var/ObjectFunctionString", + "./var/trim", "./var/support", - "./var/isFunction", "./var/isWindow", "./core/DOMEval", "./core/toType" ], function( arr, document, getProto, slice, concat, push, indexOf, class2type, toString, hasOwn, fnToString, ObjectFunctionString, - support, isFunction, isWindow, DOMEval, toType ) { + trim, support, isWindow, DOMEval, toType ) { "use strict"; @@ -35,11 +35,7 @@ var // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + }; jQuery.fn = jQuery.prototype = { @@ -139,7 +135,7 @@ jQuery.extend = jQuery.fn.extend = function() { } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { + if ( typeof target !== "object" && typeof target !== "function" ) { target = {}; } @@ -264,11 +260,8 @@ jQuery.extend( { return obj; }, - // Support: Android <=4.0 only trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); + return text == null ? "" : trim.call( text ); }, // results is for internal usage only @@ -293,8 +286,6 @@ jQuery.extend( { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, @@ -380,14 +371,10 @@ function( i, name ) { function isArrayLike( obj ) { - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, + var length = !!obj && obj.length, type = toType( obj ); - if ( isFunction( obj ) || isWindow( obj ) ) { + if ( typeof obj === "function" || isWindow( obj ) ) { return false; } diff --git a/src/core/DOMEval.js b/src/core/DOMEval.js index 59f6e024775..ff1c111a9de 100644 --- a/src/core/DOMEval.js +++ b/src/core/DOMEval.js @@ -20,7 +20,7 @@ define( [ if ( node ) { for ( i in preservedScriptAttributes ) { - // Support: Firefox 64+, Edge 18+ + // Support: Firefox <=64 - 66+, Edge <=18 only // Some browsers don't support the "nonce" property on scripts. // On the other hand, just using `getAttribute` is not enough as // the `nonce` attribute is reset to an empty string whenever it diff --git a/src/core/access.js b/src/core/access.js index 842c4a42b3f..f600600d538 100644 --- a/src/core/access.js +++ b/src/core/access.js @@ -1,8 +1,7 @@ define( [ "../core", - "../core/toType", - "../var/isFunction" -], function( jQuery, toType, isFunction ) { + "../core/toType" +], function( jQuery, toType ) { "use strict"; @@ -24,7 +23,7 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { } else if ( value !== undefined ) { chainable = true; - if ( !isFunction( value ) ) { + if ( typeof value !== "function" ) { raw = true; } diff --git a/src/core/camelCase.js b/src/core/camelCase.js index 799fb3752f7..659ca325df0 100644 --- a/src/core/camelCase.js +++ b/src/core/camelCase.js @@ -12,7 +12,7 @@ function fcamelCase( all, letter ) { } // Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 +// Support: IE <=9 - 11 only, Edge 12 - 18 only // Microsoft forgot to hump their vendor prefix (#9572) function camelCase( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); diff --git a/src/core/init.js b/src/core/init.js index 8865238c83c..71f30e926fd 100644 --- a/src/core/init.js +++ b/src/core/init.js @@ -2,11 +2,10 @@ define( [ "../core", "../var/document", - "../var/isFunction", "./var/rsingleTag", "../traversing/findFilter" -], function( jQuery, document, isFunction, rsingleTag ) { +], function( jQuery, document, rsingleTag ) { "use strict"; @@ -64,7 +63,7 @@ var rootjQuery, for ( match in context ) { // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { + if ( typeof this[ match ] === "function" ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes @@ -107,7 +106,7 @@ var rootjQuery, // HANDLE: $(function) // Shortcut for document ready - } else if ( isFunction( selector ) ) { + } else if ( typeof selector === "function" ) { return root.ready !== undefined ? root.ready( selector ) : diff --git a/src/core/parseHTML.js b/src/core/parseHTML.js index 21ff6bfa70b..8c5268fb1e2 100644 --- a/src/core/parseHTML.js +++ b/src/core/parseHTML.js @@ -2,11 +2,8 @@ define( [ "../core", "../var/document", "./var/rsingleTag", - "../manipulation/buildFragment", - - // This is the only module that needs core/support - "./support" -], function( jQuery, document, rsingleTag, buildFragment, support ) { + "../manipulation/buildFragment" +], function( jQuery, document, rsingleTag, buildFragment ) { "use strict"; @@ -29,18 +26,14 @@ jQuery.parseHTML = function( data, context, keepScripts ) { // Stop scripts or inline event handlers from being executed immediately // by using document.implementation - if ( support.createHTMLDocument ) { - context = document.implementation.createHTMLDocument( "" ); - - // Set the base href for the created document - // so any parsed elements with URLs - // are based on the document's URL (gh-2965) - base = context.createElement( "base" ); - base.href = document.location.href; - context.head.appendChild( base ); - } else { - context = document; - } + context = document.implementation.createHTMLDocument( "" ); + + // Set the base href for the created document + // so any parsed elements with URLs + // are based on the document's URL (gh-2965) + base = context.createElement( "base" ); + base.href = document.location.href; + context.head.appendChild( base ); } parsed = rsingleTag.exec( data ); diff --git a/src/core/ready-no-deferred.js b/src/core/ready-no-deferred.js index 4428020ef0b..2c3fc1b846e 100644 --- a/src/core/ready-no-deferred.js +++ b/src/core/ready-no-deferred.js @@ -1,8 +1,7 @@ define( [ "../core", - "../var/document", - "../var/isFunction" -], function( jQuery, document, isFunction ) { + "../var/document" +], function( jQuery, document ) { "use strict"; @@ -53,7 +52,7 @@ jQuery.extend( { while ( readyCallbacks.length ) { fn = readyCallbacks.shift(); - if ( isFunction( fn ) ) { + if ( typeof fn === "function" ) { executeReady( fn ); } } @@ -77,10 +76,7 @@ function completed() { // Catch cases where $(document).ready() is called // after the browser event has already occurred. -// Support: IE9-10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { +if ( document.readyState !== "loading" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); diff --git a/src/core/ready.js b/src/core/ready.js index 794feeec060..3abb6c03a39 100644 --- a/src/core/ready.js +++ b/src/core/ready.js @@ -66,10 +66,7 @@ function completed() { // Catch cases where $(document).ready() is called // after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { +if ( document.readyState !== "loading" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); diff --git a/src/core/support.js b/src/core/support.js deleted file mode 100644 index 13ae02f0857..00000000000 --- a/src/core/support.js +++ /dev/null @@ -1,20 +0,0 @@ -define( [ - "../var/document", - "../var/support" -], function( document, support ) { - -"use strict"; - -// Support: Safari 8 only -// In Safari 8 documents created via document.implementation.createHTMLDocument -// collapse sibling forms: the second one becomes a child of the first one. -// Because of that, this security measure has to be disabled in Safari 8. -// https://bugs.webkit.org/show_bug.cgi?id=137337 -support.createHTMLDocument = ( function() { - var body = document.implementation.createHTMLDocument( "" ).body; - body.innerHTML = "
"; - return body.childNodes.length === 2; -} )(); - -return support; -} ); diff --git a/src/core/toType.js b/src/core/toType.js index c77ba95ad5b..c555ef9df2c 100644 --- a/src/core/toType.js +++ b/src/core/toType.js @@ -10,8 +10,7 @@ function toType( obj ) { return obj + ""; } - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? + return typeof obj === "object" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } diff --git a/src/css.js b/src/css.js index d6354a3103d..911dd4d1682 100644 --- a/src/css.js +++ b/src/css.js @@ -130,7 +130,6 @@ function getWidthOrHeight( elem, dimension, extra ) { val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { @@ -142,15 +141,11 @@ function getWidthOrHeight( elem, dimension, extra ) { // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - // Support: IE 9-11 only + // Support: IE 9 - 11 only // Also use offsetWidth/offsetHeight for when box sizing is unreliable // We use getClientRects() to check for hidden/disconnected. // In those cases, the computed value can be trusted to be border-box - if ( ( !support.boxSizingReliable() && isBorderBox || - val === "auto" || - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + if ( ( !support.boxSizingReliable() && isBorderBox || val === "auto" ) && elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; @@ -328,12 +323,12 @@ jQuery.each( [ "height", "width" ], function( i, dimension ) { // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. + // Support: Safari <=8 - 12+, Chrome <=73+ + // Table columns in WebKit/Blink have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); @@ -346,14 +341,8 @@ jQuery.each( [ "height", "width" ], function( i, dimension ) { var matches, styles = getStyles( elem ), - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && + isBorderBox = extra && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra ? boxModelAdjustment( @@ -365,17 +354,6 @@ jQuery.each( [ "height", "width" ], function( i, dimension ) { ) : 0; - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { diff --git a/src/css/adjustCSS.js b/src/css/adjustCSS.js index 4e3e6c37a60..5341a789060 100644 --- a/src/css/adjustCSS.js +++ b/src/css/adjustCSS.js @@ -26,7 +26,7 @@ function adjustCSS( elem, prop, valueParts, tween ) { if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - // Support: Firefox <=54 + // Support: Firefox <=54 - 66+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 98a594a7705..cb9f418764c 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -20,9 +20,7 @@ function curCSS( elem, name, computed ) { computed = computed || getStyles( elem ); - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) + // getPropertyValue is needed for `.css('--customProperty')` (gh-3144) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; @@ -30,8 +28,9 @@ function curCSS( elem, name, computed ) { ret = jQuery.style( elem, name ); } + // Support: iOS <=10 only // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, + // Old WebKit returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values diff --git a/src/css/support.js b/src/css/support.js index 9c4da57d935..9f539fc9ee3 100644 --- a/src/css/support.js +++ b/src/css/support.js @@ -29,10 +29,10 @@ define( [ var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 60 only reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Support: iOS <=7.0 - 10.3 only // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; @@ -41,13 +41,6 @@ define( [ // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and @@ -59,7 +52,7 @@ define( [ return Math.round( parseFloat( measure ) ); } - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + var pixelPositionVal, boxSizingReliableVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); @@ -91,10 +84,6 @@ define( [ reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; } } ); } )(); diff --git a/src/css/var/getStyles.js b/src/css/var/getStyles.js index 0b893acf0b2..e42db98aa78 100644 --- a/src/css/var/getStyles.js +++ b/src/css/var/getStyles.js @@ -3,11 +3,18 @@ define( function() { return function( elem ) { - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + // Support: IE <=11 only (trac-14150) + // In IE popups `window` is the opener window which makes `window.getComputedStyle( elem )` + // break. Using `elem.ownerDocument.defaultView` avoids the issue. var view = elem.ownerDocument.defaultView; + // `document.implementation.createHTMLDocument( "" )` has a `null` `defaultView` + // property; check `defaultView` truthiness to fallback to window in such a case. + // + // Support: Firefox <=30 - 61 only (trac-15098) + // Firefox throws on frame elements through "defaultView.getComputedStyle". Check for + // `opener` to only rely on `elem.ownerDocument.defaultView` in popups. This is enough + // to work around both the IE & Firefox issues. if ( !view || !view.opener ) { view = window; } diff --git a/src/css/var/isHiddenWithinTree.js b/src/css/var/isHiddenWithinTree.js index 0ab610e2941..950b808db35 100644 --- a/src/css/var/isHiddenWithinTree.js +++ b/src/css/var/isHiddenWithinTree.js @@ -24,7 +24,7 @@ define( [ elem.style.display === "" && // Otherwise, check computed style - // Support: Firefox <=43 - 45 + // Support: Firefox <=43 - 64 only // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. isAttached( elem ) && diff --git a/src/data/Data.js b/src/data/Data.js index 31ff4318c17..c94480fcd57 100644 --- a/src/data/Data.js +++ b/src/data/Data.js @@ -141,7 +141,7 @@ Data.prototype = { // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - // Support: Chrome <=35 - 45 + // Support: Chrome <=35 - 45+ // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) diff --git a/src/deferred.js b/src/deferred.js index 0425d3631ff..81a1d0140f0 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -1,9 +1,8 @@ define( [ "./core", - "./var/isFunction", "./var/slice", "./callbacks" -], function( jQuery, isFunction, slice ) { +], function( jQuery, slice ) { "use strict"; @@ -20,11 +19,11 @@ function adoptValue( value, resolve, reject, noValue ) { try { // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { + if ( value && typeof( method = value.promise ) === "function" ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { + } else if ( value && typeof( method = value.then ) === "function" ) { method.call( value, resolve, reject ); // Other non-thenables @@ -40,10 +39,7 @@ function adoptValue( value, resolve, reject, noValue ) { // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); + reject( value ); } } @@ -70,7 +66,7 @@ jQuery.extend( { deferred.done( arguments ).fail( arguments ); return this; }, - "catch": function( fn ) { + catch: function( fn ) { return promise.then( null, fn ); }, @@ -82,14 +78,15 @@ jQuery.extend( { jQuery.each( tuples, function( i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + var fn = typeof fns[ tuple[ 4 ] ] === "function" && + fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { + if ( returned && typeof returned.promise === "function" ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) @@ -143,7 +140,7 @@ jQuery.extend( { returned.then; // Handle a returned thenable - if ( isFunction( then ) ) { + if ( typeof then === "function" ) { // Special processors (notify) just wait for resolution if ( special ) { @@ -239,7 +236,7 @@ jQuery.extend( { resolve( 0, newDefer, - isFunction( onProgress ) ? + typeof onProgress === "function" ? onProgress : Identity, newDefer.notifyWith @@ -251,7 +248,7 @@ jQuery.extend( { resolve( 0, newDefer, - isFunction( onFulfilled ) ? + typeof onFulfilled === "function" ? onFulfilled : Identity ) @@ -262,7 +259,7 @@ jQuery.extend( { resolve( 0, newDefer, - isFunction( onRejected ) ? + typeof onRejected === "function" ? onRejected : Thrower ) @@ -380,7 +377,7 @@ jQuery.extend( { // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + typeof( resolveValues[ i ] && resolveValues[ i ].then ) === "function" ) { return master.then(); } diff --git a/src/deferred/exceptionHook.js b/src/deferred/exceptionHook.js index 6dbdc85208c..f6faf41231d 100644 --- a/src/deferred/exceptionHook.js +++ b/src/deferred/exceptionHook.js @@ -11,10 +11,12 @@ var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + if ( error && rerrorNames.test( error.name ) ) { + window.console.warn( + "jQuery.Deferred exception: " + error.message, + error.stack, + stack + ); } }; diff --git a/src/deprecated.js b/src/deprecated.js index c11b0d33245..7c67b75e349 100644 --- a/src/deprecated.js +++ b/src/deprecated.js @@ -3,12 +3,11 @@ define( [ "./core/nodeName", "./core/camelCase", "./core/toType", - "./var/isFunction", "./var/isWindow", "./var/slice", "./event/alias" -], function( jQuery, nodeName, camelCase, toType, isFunction, isWindow, slice ) { +], function( jQuery, nodeName, camelCase, toType, isWindow, slice ) { "use strict"; @@ -48,7 +47,7 @@ jQuery.proxy = function( fn, context ) { // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. - if ( !isFunction( fn ) ) { + if ( typeof fn !== "function" ) { return undefined; } @@ -74,13 +73,16 @@ jQuery.holdReady = function( hold ) { jQuery.isArray = Array.isArray; jQuery.parseJSON = JSON.parse; jQuery.nodeName = nodeName; -jQuery.isFunction = isFunction; jQuery.isWindow = isWindow; jQuery.camelCase = camelCase; jQuery.type = toType; jQuery.now = Date.now; +jQuery.isFunction = function( obj ) { + return typeof obj === "function"; +}; + jQuery.isNumeric = function( obj ) { // As of jQuery 3.0, isNumeric is limited to diff --git a/src/effects.js b/src/effects.js index a778de106ac..3630177b707 100644 --- a/src/effects.js +++ b/src/effects.js @@ -2,7 +2,6 @@ define( [ "./core", "./core/camelCase", "./var/document", - "./var/isFunction", "./var/rcssNum", "./var/rnothtmlwhite", "./css/var/cssExpand", @@ -19,7 +18,7 @@ define( [ "./manipulation", "./css", "./effects/Tween" -], function( jQuery, camelCase, document, isFunction, rcssNum, rnothtmlwhite, cssExpand, +], function( jQuery, camelCase, document, rcssNum, rnothtmlwhite, cssExpand, isHiddenWithinTree, swap, adjustCSS, dataPriv, showHide ) { "use strict"; @@ -150,7 +149,7 @@ function defaultPrefilter( elem, props, opts ) { // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { - // Support: IE <=9 - 11, Edge 12 - 15 + // Support: IE <=9 - 11 only, Edge 12 - 18 only // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. @@ -310,10 +309,7 @@ function Animation( elem, properties, options ) { var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, + percent = 1 - ( remaining / animation.duration || 0 ), index = 0, length = animation.tweens.length; @@ -386,7 +382,7 @@ function Animation( elem, properties, options ) { for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { - if ( isFunction( result.stop ) ) { + if ( typeof result.stop === "function" ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } @@ -396,7 +392,7 @@ function Animation( elem, properties, options ) { jQuery.map( props, createTween, animation ); - if ( isFunction( animation.opts.start ) ) { + if ( typeof animation.opts.start === "function" ) { animation.opts.start.call( elem, animation ); } @@ -429,7 +425,7 @@ jQuery.Animation = jQuery.extend( Animation, { }, tweener: function( props, callback ) { - if ( isFunction( props ) ) { + if ( typeof props === "function" ) { callback = props; props = [ "*" ]; } else { @@ -461,9 +457,9 @@ jQuery.Animation = jQuery.extend( Animation, { jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || - isFunction( speed ) && speed, + typeof speed === "function" && speed, duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing + easing: fn && easing || easing && typeof easing !== "function" && easing }; // Go to the end state if fx are off @@ -490,7 +486,7 @@ jQuery.speed = function( speed, easing, fn ) { opt.old = opt.complete; opt.complete = function() { - if ( isFunction( opt.old ) ) { + if ( typeof opt.old === "function" ) { opt.old.call( this ); } diff --git a/src/effects/Tween.js b/src/effects/Tween.js index f8c847f9723..0c5fe67d35d 100644 --- a/src/effects/Tween.js +++ b/src/effects/Tween.js @@ -98,16 +98,6 @@ Tween.propHooks = { } }; -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - jQuery.easing = { linear: function( p ) { return p; diff --git a/src/event.js b/src/event.js index b63b93b96ca..e784009409f 100644 --- a/src/event.js +++ b/src/event.js @@ -2,7 +2,6 @@ define( [ "./core", "./var/document", "./var/documentElement", - "./var/isFunction", "./var/rnothtmlwhite", "./var/rcheckableType", "./var/slice", @@ -11,7 +10,7 @@ define( [ "./core/init", "./selector" -], function( jQuery, document, documentElement, isFunction, rnothtmlwhite, +], function( jQuery, document, documentElement, rnothtmlwhite, rcheckableType, slice, dataPriv, nodeName ) { "use strict"; @@ -29,23 +28,14 @@ function returnFalse() { return false; } -// Support: IE <=9 - 11+ +// Support: IE <=9 - 11 only // focus() and blur() are asynchronous, except when they are no-op. // So expect focus to be synchronous when the element is already active, // and blur to be synchronous when the element is not already active. // (focus and blur are always synchronous in other supported browsers, // this just defines when we can count on it). function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } + return ( elem === document.activeElement ) === ( type === "focus" ); } function on( elem, types, selector, data, fn, one ) { @@ -379,11 +369,7 @@ jQuery.event = { // Find delegate handlers if ( delegateCount && - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 + // Support: Firefox <=42 - 66+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only @@ -433,7 +419,7 @@ jQuery.event = { enumerable: true, configurable: true, - get: isFunction( hook ) ? + get: typeof hook === "function" ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); @@ -521,8 +507,9 @@ jQuery.event = { beforeunload: { postDispatch: function( event ) { - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. + // Support: Chrome <=73+ + // Chrome doesn't alert on `event.preventDefault()` + // as the standard mandates. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } @@ -561,7 +548,7 @@ function leverageNative( el, type, expectSync ) { dataPriv.set( this, type, saved ); // Trigger the native event and capture its result - // Support: IE <=9 - 11+ + // Support: IE <=9 - 11 only // focus() and blur() are asynchronous notAsync = expectSync( this, type ); this[ type ](); @@ -596,7 +583,7 @@ function leverageNative( el, type, expectSync ) { // ...and capture the result dataPriv.set( this, type, jQuery.event.trigger( - // Support: IE <=9 - 11+ + // Support: IE <=9 - 11 only // Extend with the prototype to reset the above stopImmediatePropagation() jQuery.extend( saved.shift(), jQuery.Event.prototype ), saved, @@ -632,21 +619,12 @@ jQuery.Event = function( src, props ) { // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? + this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse; // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - + this.target = src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; @@ -799,11 +777,6 @@ jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateTyp // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", diff --git a/src/event/focusin.js b/src/event/focusin.js index 7faef298134..f1a09afb1e3 100644 --- a/src/event/focusin.js +++ b/src/event/focusin.js @@ -9,11 +9,7 @@ define( [ "use strict"; -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// Support: Firefox 52 - 66+, Chrome <=48 - 73+, Safari <=9.0 - 12+, Edge <=17 - 18+ // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 diff --git a/src/event/trigger.js b/src/event/trigger.js index cf40b4faabf..39f641b70bb 100644 --- a/src/event/trigger.js +++ b/src/event/trigger.js @@ -4,10 +4,9 @@ define( [ "../data/var/dataPriv", "../data/var/acceptData", "../var/hasOwn", - "../var/isFunction", "../var/isWindow", "../event" -], function( jQuery, document, dataPriv, acceptData, hasOwn, isFunction, isWindow ) { +], function( jQuery, document, dataPriv, acceptData, hasOwn, isWindow ) { "use strict"; @@ -129,7 +128,7 @@ jQuery.extend( jQuery.event, { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + if ( ontype && typeof elem[ type ] === "function" && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; diff --git a/src/manipulation.js b/src/manipulation.js index ab19d8b3cd7..0b088a44476 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -2,7 +2,6 @@ define( [ "./core", "./core/isAttached", "./var/concat", - "./var/isFunction", "./var/push", "./var/rcheckableType", "./core/access", @@ -24,7 +23,7 @@ define( [ "./traversing", "./selector", "./event" -], function( jQuery, isAttached, concat, isFunction, push, rcheckableType, +], function( jQuery, isAttached, concat, push, rcheckableType, access, rtagName, rscriptType, wrapMap, getAll, setGlobalEval, buildFragment, support, dataPriv, dataUser, acceptData, DOMEval, nodeName ) { @@ -40,13 +39,11 @@ var /* eslint-enable */ - // Support: IE <=10 - 11, Edge 12 - 13 only + // Support: IE <=10 - 11 only, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; // Prefer a tbody over its parent table for containing new rows @@ -109,20 +106,6 @@ function cloneCopyEvent( src, dest ) { } } -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays @@ -133,17 +116,12 @@ function domManip( collection, args, callback, ignored ) { l = collection.length, iNoClone = l - 1, value = args[ 0 ], - valueIsFunction = isFunction( value ); + valueIsFunction = typeof value === "function"; - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { + if ( valueIsFunction ) { return collection.each( function( index ) { var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } + args[ 0 ] = value.call( this, index, self.html() ); domManip( self, args, callback, ignored ); } ); } @@ -172,9 +150,6 @@ function domManip( collection, args, callback, ignored ) { // Keep references to cloned scripts for later restoration if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } @@ -255,7 +230,13 @@ jQuery.extend( { srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); + + // Support: IE <=11 only + // IE fails to set the defaultValue to the correct value when + // cloning other types of input fields + if ( destElements[ i ].nodeName.toLowerCase() === "textarea" ) { + destElements[ i ].defaultValue = srcElements[ i ].defaultValue; + } } } @@ -475,9 +456,6 @@ jQuery.each( { for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } diff --git a/src/manipulation/buildFragment.js b/src/manipulation/buildFragment.js index 40c2ed1dcae..01dcff6e562 100644 --- a/src/manipulation/buildFragment.js +++ b/src/manipulation/buildFragment.js @@ -27,9 +27,6 @@ function buildFragment( elems, context, scripts, selection, ignored ) { // Add nodes directly if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node @@ -51,8 +48,6 @@ function buildFragment( elems, context, scripts, selection, ignored ) { tmp = tmp.lastChild; } - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container diff --git a/src/manipulation/support.js b/src/manipulation/support.js index 4a5d9af4cca..ea445403722 100644 --- a/src/manipulation/support.js +++ b/src/manipulation/support.js @@ -10,20 +10,13 @@ define( [ div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); div.appendChild( input ); - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; diff --git a/src/offset.js b/src/offset.js index 83b1c3a533e..2a633bd5cb1 100644 --- a/src/offset.js +++ b/src/offset.js @@ -3,7 +3,6 @@ define( [ "./core/access", "./var/document", "./var/documentElement", - "./var/isFunction", "./css/var/rnumnonpx", "./css/curCSS", "./css/addGetHookIf", @@ -12,7 +11,7 @@ define( [ "./core/init", "./css", "./selector" // contains -], function( jQuery, access, document, documentElement, isFunction, rnumnonpx, +], function( jQuery, access, document, documentElement, rnumnonpx, curCSS, addGetHookIf, support, isWindow ) { "use strict"; @@ -47,7 +46,7 @@ jQuery.offset = { curLeft = parseFloat( curCSSLeft ) || 0; } - if ( isFunction( options ) ) { + if ( typeof options === "function" ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); @@ -208,10 +207,9 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( }; } ); -// Support: Safari <=7 - 9.1, Chrome <=37 - 49 +// Support: iOS <=7.0 - 10.3 only // Add the top/left cssHooks using jQuery.fn.position // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 -// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 // getComputedStyle returns percent when specified for top/left/bottom/right; // rather than make the css module depend on the offset module, just check for it here jQuery.each( [ "top", "left" ], function( i, prop ) { diff --git a/src/selector-native.js b/src/selector-native.js index da837a00462..658e43b64d3 100644 --- a/src/selector-native.js +++ b/src/selector-native.js @@ -35,11 +35,7 @@ define( [ var hasDuplicate, sortInput, sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando, - matches = documentElement.matches || - documentElement.webkitMatchesSelector || - documentElement.mozMatchesSelector || - documentElement.oMatchesSelector || - documentElement.msMatchesSelector, + matches = documentElement.matches || documentElement.msMatchesSelector, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms diff --git a/src/serialize.js b/src/serialize.js index d8a9a36a4f2..0cf5ddb44d8 100644 --- a/src/serialize.js +++ b/src/serialize.js @@ -2,11 +2,10 @@ define( [ "./core", "./core/toType", "./var/rcheckableType", - "./var/isFunction", "./core/init", "./traversing", // filter "./attributes/prop" -], function( jQuery, toType, rcheckableType, isFunction ) { +], function( jQuery, toType, rcheckableType ) { "use strict"; @@ -62,7 +61,7 @@ jQuery.param = function( a, traditional ) { add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? + var value = typeof valueOrFunction === "function" ? valueOrFunction() : valueOrFunction; diff --git a/src/traversing.js b/src/traversing.js index 426d5b6ea31..1a468425fe9 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -149,7 +149,7 @@ jQuery.each( { return elem.contentDocument; } - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Support: IE 9 - 11 only // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { diff --git a/src/traversing/findFilter.js b/src/traversing/findFilter.js index 268dad796c1..2f526b71381 100644 --- a/src/traversing/findFilter.js +++ b/src/traversing/findFilter.js @@ -1,16 +1,15 @@ define( [ "../core", "../var/indexOf", - "../var/isFunction", "./var/rneedsContext", "../selector" -], function( jQuery, indexOf, isFunction, rneedsContext ) { +], function( jQuery, indexOf, rneedsContext ) { "use strict"; // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { + if ( typeof qualifier === "function" ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); diff --git a/src/var/isFunction.js b/src/var/isFunction.js deleted file mode 100644 index dad662e4fd2..00000000000 --- a/src/var/isFunction.js +++ /dev/null @@ -1,13 +0,0 @@ -define( function() { - "use strict"; - - return function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; - -} ); diff --git a/src/var/trim.js b/src/var/trim.js new file mode 100644 index 00000000000..a5e75af36e6 --- /dev/null +++ b/src/var/trim.js @@ -0,0 +1,5 @@ +define( function() { + "use strict"; + + return "".trim; +} ); diff --git a/src/wrap.js b/src/wrap.js index 41b716f9f78..a42c04da75d 100644 --- a/src/wrap.js +++ b/src/wrap.js @@ -1,10 +1,9 @@ define( [ "./core", - "./var/isFunction", "./core/init", "./manipulation", // clone "./traversing" // parent, contents -], function( jQuery, isFunction ) { +], function( jQuery ) { "use strict"; @@ -13,7 +12,7 @@ jQuery.fn.extend( { var wrap; if ( this[ 0 ] ) { - if ( isFunction( html ) ) { + if ( typeof html === "function" ) { html = html.call( this[ 0 ] ); } @@ -39,7 +38,7 @@ jQuery.fn.extend( { }, wrapInner: function( html ) { - if ( isFunction( html ) ) { + if ( typeof html === "function" ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); @@ -59,7 +58,7 @@ jQuery.fn.extend( { }, wrap: function( html ) { - var htmlIsFunction = isFunction( html ); + var htmlIsFunction = typeof html === "function"; return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); diff --git a/src/wrapper.js b/src/wrapper.js index 0af1f496443..7af4ad75eca 100644 --- a/src/wrapper.js +++ b/src/wrapper.js @@ -40,10 +40,6 @@ // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. "use strict"; // @CODE diff --git a/test/data/core/cc_on.html b/test/data/core/cc_on.html deleted file mode 100644 index 5db18916ca1..00000000000 --- a/test/data/core/cc_on.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - diff --git a/test/data/testinit.js b/test/data/testinit.js index e1d81c5c7a2..eb49010626e 100644 --- a/test/data/testinit.js +++ b/test/data/testinit.js @@ -1,5 +1,7 @@ /* eslint no-multi-str: "off" */ +"use strict"; + var FILEPATH = "/test/data/testinit.js", activeScript = [].slice.call( document.getElementsByTagName( "script" ), -1 )[ 0 ], parentUrl = activeScript && activeScript.src ? @@ -100,43 +102,9 @@ this.createDashboardXML = function() { return jQuery.parseXML( string ); }; -this.createWithFriesXML = function() { - var string = " \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - 1 \ - \ - \ - \ - \ - foo \ - \ - \ - \ - \ - \ - \ - "; - - return jQuery.parseXML( string.replace( /\{\{\s*externalHost\s*\}\}/g, externalHost ) ); -}; - this.createXMLFragment = function() { - var xml, frag; - if ( window.ActiveXObject ) { - xml = new window.ActiveXObject( "msxml2.domdocument" ); - } else { + var frag, xml = document.implementation.createDocument( "", "", null ); - } if ( xml ) { frag = xml.createElement( "data" ); @@ -314,10 +282,9 @@ this.loadTests = function() { require( [ parentUrl + "test/data/testrunner.js" ], function() { var i = 0, tests = [ - // A special module with basic tests, meant for - // not fully supported environments like Android 2.3, - // jsdom or PhantomJS. We run it everywhere, though, - // to make sure tests are not broken. + // A special module with basic tests, meant for not fully + // supported environments like jsdom. We run it everywhere, + // though, to make sure tests are not broken. "unit/basic.js", "unit/core.js", @@ -351,7 +318,6 @@ this.loadTests = function() { if ( !QUnit.basicTests || i === 1 ) { require( [ parentUrl + "test/" + dep ], loadDep ); - // Support: Android 2.3 only // When running basic tests, replace other modules with dummies to avoid overloading // impaired clients. } else { diff --git a/test/data/testrunner.js b/test/data/testrunner.js index 39000c33b40..c4fa5d378d2 100644 --- a/test/data/testrunner.js +++ b/test/data/testrunner.js @@ -1,5 +1,7 @@ ( function() { +"use strict"; + // Store the old counts so that we only assert on tests that have actually leaked, // instead of asserting every time a test has leaked sometime in the past var oldCacheLength = 0, diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 7bf3f686b1d..90c5cd72a48 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -120,9 +120,7 @@ QUnit.module( "ajax", { assert.ok( true, "success" ); }, fail: function() { - if ( jQuery.support.cors === false ) { - assert.ok( true, "fail" ); - } + assert.ok( false, "fail" ); }, complete: function() { assert.ok( true, "complete" ); @@ -269,13 +267,12 @@ QUnit.module( "ajax", { "Nullable": null, "undefined": undefined - // Support: IE 9 - 11, Edge 12 - 14 only + // Support: IE 9 - 11 only, Edge 12 - 14 only // Not all browsers allow empty-string headers //"Empty": "" }, success: function( data, _, xhr ) { var i, emptyHeader, - isAndroid = /android 4\.[0-3]/i.test( navigator.userAgent ), requestHeaders = jQuery.extend( this.headers, { "ajax-send": "test" } ), @@ -296,25 +293,8 @@ QUnit.module( "ajax", { assert.strictEqual( emptyHeader, "", "Empty header received" ); } assert.strictEqual( xhr.getResponseHeader( "Sample-Header2" ), "Hello World 2", "Second sample header received" ); - - if ( isAndroid ) { - // Support: Android 4.0-4.3 only - // Android Browser only returns the last value for each header - // so there's no way for jQuery get all parts. - assert.ok( true, "Android doesn't support repeated header names" ); - } else { - assert.strictEqual( xhr.getResponseHeader( "List-Header" ), "Item 1, Item 2", "List header received" ); - } - - if ( isAndroid && QUnit.isSwarm ) { - // Support: Android 4.0-4.3 on BrowserStack only - // Android Browser versions provided by BrowserStack fail this test - // while locally fired emulators don't, even when they connect - // to TestSwarm. Just skip the test there to avoid a red build. - assert.ok( true, "BrowserStack's Android fails the \"prototype collision (constructor)\" test" ); - } else { - assert.strictEqual( xhr.getResponseHeader( "constructor" ), "prototype collision (constructor)", "constructor header received" ); - } + assert.strictEqual( xhr.getResponseHeader( "List-Header" ), "Item 1, Item 2", "List header received" ); + assert.strictEqual( xhr.getResponseHeader( "constructor" ), "prototype collision (constructor)", "constructor header received" ); assert.strictEqual( xhr.getResponseHeader( "__proto__" ), null, "Undefined __proto__ header not received" ); } }; @@ -553,47 +533,41 @@ QUnit.module( "ajax", { }; } ); - if ( !/android 4\.0/i.test( navigator.userAgent ) ) { - ajaxTest( "jQuery.ajax() - native abort", 2, function( assert ) { - return { - url: url( "mock.php?action=wait&wait=1" ), - xhr: function() { - var xhr = new window.XMLHttpRequest(); - setTimeout( function() { - xhr.abort(); - }, 100 ); - return xhr; - }, - error: function( xhr, msg ) { - assert.strictEqual( msg, "error", "Native abort triggers error callback" ); - }, - complete: function() { - assert.ok( true, "complete" ); - } - }; - } ); - } + ajaxTest( "jQuery.ajax() - native abort", 2, function( assert ) { + return { + url: url( "mock.php?action=wait&wait=1" ), + xhr: function() { + var xhr = new window.XMLHttpRequest(); + setTimeout( function() { + xhr.abort(); + }, 100 ); + return xhr; + }, + error: function( xhr, msg ) { + assert.strictEqual( msg, "error", "Native abort triggers error callback" ); + }, + complete: function() { + assert.ok( true, "complete" ); + } + }; + } ); - // Support: Android <= 4.0 - 4.3 only - // Android 4.0-4.3 does not have ontimeout on an xhr - if ( "ontimeout" in new window.XMLHttpRequest() ) { - ajaxTest( "jQuery.ajax() - native timeout", 2, function( assert ) { - return { - url: url( "mock.php?action=wait&wait=1" ), - xhr: function() { - var xhr = new window.XMLHttpRequest(); - xhr.timeout = 1; - return xhr; - }, - error: function( xhr, msg ) { - assert.strictEqual( msg, "error", "Native timeout triggers error callback" ); - }, - complete: function() { - assert.ok( true, "complete" ); - } - }; - } ); - } + ajaxTest( "jQuery.ajax() - native timeout", 2, function( assert ) { + return { + url: url( "mock.php?action=wait&wait=1" ), + xhr: function() { + var xhr = new window.XMLHttpRequest(); + xhr.timeout = 1; + return xhr; + }, + error: function( xhr, msg ) { + assert.strictEqual( msg, "error", "Native timeout triggers error callback" ); + }, + complete: function() { + assert.ok( true, "complete" ); + } + }; + } ); ajaxTest( "jQuery.ajax() - events with context", 12, function( assert ) { var context = document.createElement( "div" ); diff --git a/test/unit/basic.js b/test/unit/basic.js index bed27dcbabe..8b567f19578 100644 --- a/test/unit/basic.js +++ b/test/unit/basic.js @@ -179,7 +179,11 @@ QUnit.test( "manipulation", function( assert ) { ".html getter/setter" ); - assert.strictEqual( elem1.append( elem2 )[ 0 ].childNodes[ 1 ], elem2[ 0 ], ".append" ); + assert.strictEqual( + elem1.append( elem2 )[ 0 ].childNodes[ elem1[ 0 ].childNodes.length - 1 ], + elem2[ 0 ], + ".append" + ); assert.strictEqual( elem1.prepend( elem2 )[ 0 ].childNodes[ 0 ], elem2[ 0 ], ".prepend" ); child = elem1.find( "span" ); diff --git a/test/unit/core.js b/test/unit/core.js index 3cb2d39514b..35af322da32 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -1371,30 +1371,14 @@ QUnit.test( "jQuery.parseXML", function( assert ) { } ); testIframe( - "Conditional compilation compatibility (#13274)", - "core/cc_on.html", - function( assert, jQuery, window, document, cc_on, errors ) { - assert.expect( 3 ); - assert.ok( true, "JScript conditional compilation " + ( cc_on ? "supported" : "not supported" ) ); - assert.deepEqual( errors, [], "No errors" ); - assert.ok( jQuery(), "jQuery executes" ); + "document ready when jQuery loaded asynchronously (#13655)", + "core/dynamic_ready.html", + function( assert, jQuery, window, document, ready ) { + assert.expect( 1 ); + assert.equal( true, ready, "document ready correctly fired when jQuery is loaded after DOMContentLoaded" ); } ); -// iOS7 doesn't fire the load event if the long-loading iframe gets its source reset to about:blank. -// This makes this test fail but it doesn't seem to cause any real-life problems so blacklisting -// this test there is preferred to complicating the hard-to-test core/ready code further. -if ( !/iphone os 7_/i.test( navigator.userAgent ) ) { - testIframe( - "document ready when jQuery loaded asynchronously (#13655)", - "core/dynamic_ready.html", - function( assert, jQuery, window, document, ready ) { - assert.expect( 1 ); - assert.equal( true, ready, "document ready correctly fired when jQuery is loaded after DOMContentLoaded" ); - } - ); -} - testIframe( "Tolerating alias-masked DOM properties (#14074)", "core/aliased.html", diff --git a/test/unit/css.js b/test/unit/css.js index 20a5a77bc4e..d003e2a0f38 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1437,16 +1437,6 @@ QUnit.test( "certain css values of 'normal' should be convertable to a number, s assert.equal( typeof el.css( "fontWeight" ), "string", ".css() returns a string" ); } ); -// Support: IE 9 only -// Only run this test in IE9 -if ( document.documentMode === 9 ) { - QUnit.test( ".css('filter') returns a string in IE9, see #12537", function( assert ) { - assert.expect( 1 ); - - assert.equal( jQuery( "
" ).css( "filter" ), "progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFFFFF, endColorstr=#ECECEC)", "IE9 returns the correct value from css('filter')." ); - } ); -} - QUnit.test( "cssHooks - expand", function( assert ) { assert.expect( 15 ); var result, @@ -1506,9 +1496,9 @@ QUnit.test( "css opacity consistency across browsers (#12685)", function( assert } ); QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", function( assert ) { - assert.expect( 17 ); + assert.expect( 18 ); - var $div, $table, $a; + var $div, $table, $a, $br; assert.ok( jQuery( "#nothiddendiv" ).is( ":visible" ), "Modifying CSS display: Assert element is visible" ); jQuery( "#nothiddendiv" ).css( { display: "none" } ); @@ -1530,10 +1520,8 @@ QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", fu $div.css( { width: 0, height: 0, overflow: "hidden" } ); assert.ok( $div.is( ":visible" ), "Div with width and height of 0 is still visible (gh-2227)" ); - // Safari 6-7 and iOS 6-7 report 0 width for br elements - // When newer browsers propagate, re-enable this test - // $br = jQuery( "
" ).appendTo( "#qunit-fixture" ); - // assert.ok( $br.is( ":visible" ), "br element is visible" ); + $br = jQuery( "
" ).appendTo( "#qunit-fixture" ); + assert.ok( $br.is( ":visible" ), "br element is visible" ); $table = jQuery( "#table" ); $table.html( "cellcell" ); @@ -1556,11 +1544,7 @@ QUnit.test( "Keep the last style if the new one isn't recognized by the browser assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting an unrecognized value" ); } ); -// Support: Edge 14 - 16 only -// Edge collapses whitespace-only values when setting a style property and -// there is no easy way for us to work around it. Just skip the test there -// and hope for the better future. -QUnit[ /\bedge\/16\./i.test( navigator.userAgent ) ? "skip" : "test" ]( +QUnit.test( "Keep the last style if the new one is a non-empty whitespace (gh-3204)", function( assert ) { assert.expect( 1 ); @@ -1665,25 +1649,14 @@ QUnit.test( } ); -// Support: IE <=10 only -// We have to jump through the hoops here in order to test work with "order" CSS property, -// that some browsers do not support. This test is not, strictly speaking, correct, -// but it's the best that we can do. -( function() { - var style = document.createElement( "div" ).style, - exist = "order" in style || "WebkitOrder" in style; - - if ( exist ) { - QUnit.test( "Don't append px to CSS \"order\" value (#14049)", function( assert ) { - assert.expect( 1 ); +QUnit.test( "Don't append px to CSS \"order\" value (#14049)", function( assert ) { + assert.expect( 1 ); - var $elem = jQuery( "
" ); + var $elem = jQuery( "
" ); - $elem.css( "order", 2 ); - assert.equal( $elem.css( "order" ), "2", "2 on order" ); - } ); - } -} )(); + $elem.css( "order", 2 ); + assert.equal( $elem.css( "order" ), "2", "2 on order" ); +} ); QUnit.test( "Do not throw on frame elements from css method (#15098)", function( assert ) { assert.expect( 1 ); @@ -1815,15 +1788,13 @@ QUnit.test( "Do not throw on frame elements from css method (#15098)", function( var div = jQuery( "
" ).appendTo( "#qunit-fixture" ), $elem = jQuery( "
" ).addClass( "test__customProperties" ) .appendTo( "#qunit-fixture" ), - webkit = /\bsafari\b/i.test( navigator.userAgent ) && - !/\firefox\b/i.test( navigator.userAgent ) && - !/\edge\b/i.test( navigator.userAgent ), - oldSafari = webkit && ( /\b9\.\d(\.\d+)* safari/i.test( navigator.userAgent ) || - /\b10\.0(\.\d+)* safari/i.test( navigator.userAgent ) || - /iphone os (?:9|10)_/i.test( navigator.userAgent ) ), + webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ) && + !/\bfirefox\b/i.test( navigator.userAgent ) && + !/\bedge\b/i.test( navigator.userAgent ), + oldSafari = /iphone os 10_/i.test( navigator.userAgent ), expected = 10; - if ( webkit ) { + if ( webkitOrBlink ) { expected -= 2; } if ( oldSafari ) { @@ -1852,17 +1823,17 @@ QUnit.test( "Do not throw on frame elements from css method (#15098)", function( assert.equal( $elem.css( "--prop1" ), "val1", "Basic CSS custom property" ); - // Support: Safari 9.1-10.0 only - // Safari collapses whitespaces & quotes. Ignore it. + // Support: iOS <=10 only + // Old Safari collapses whitespaces & quotes. Ignore it. if ( !oldSafari ) { assert.equal( $elem.css( "--prop2" ), " val2", "Preceding whitespace maintained" ); assert.equal( $elem.css( "--prop3" ), "val3 ", "Following whitespace maintained" ); } - // Support: Chrome 49-55, Safari 9.1-10.0 + // Support: Chrome <=49 - 73+, Safari <=9.1 - 12.1+ // Chrome treats single quotes as double ones. // Safari treats double quotes as single ones. - if ( !webkit ) { + if ( !webkitOrBlink ) { assert.equal( $elem.css( "--prop4" ), "\"val4\"", "Works with double quotes" ); assert.equal( $elem.css( "--prop5" ), "'val5'", "Works with single quotes" ); } diff --git a/test/unit/deferred.js b/test/unit/deferred.js index c704f905f9e..936a57524e2 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -172,7 +172,7 @@ QUnit.test( "jQuery.Deferred.catch", function( assert ) { var value1, value2, value3, defer = jQuery.Deferred(), - piped = defer[ "catch" ]( function( a, b ) { + piped = defer.catch( function( a, b ) { return a * b; } ), done = jQuery.map( new Array( 3 ), function() { return assert.async(); } ); @@ -186,18 +186,18 @@ QUnit.test( "jQuery.Deferred.catch", function( assert ) { value2 = b; } ); - defer.reject( 2, 3 )[ "catch" ]( function() { + defer.reject( 2, 3 ).catch( function() { assert.strictEqual( value1, 2, "first reject value ok" ); assert.strictEqual( value2, 3, "second reject value ok" ); assert.strictEqual( value3, 6, "result of filter ok" ); done.pop().call(); } ); - jQuery.Deferred().resolve()[ "catch" ]( function() { + jQuery.Deferred().resolve().catch( function() { assert.ok( false, "then should not be called on resolve" ); } ).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" ); done.pop().call(); } ); @@ -563,8 +563,7 @@ QUnit[ typeof Symbol === "function" && Symbol.toStringTag ? "test" : "skip" ]( } ); -// Test fails in IE9 but is skipped there because console is not active -QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook", function( assert ) { +QUnit.test( "jQuery.Deferred.exceptionHook", function( assert ) { assert.expect( 2 ); @@ -573,24 +572,10 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook", func oldWarn = window.console.warn; window.console.warn = function() { - - // Support: Chrome <=41 only - // Some Chrome versions newer than 30 but older than 42 display the "undefined is - // not a function" error, not mentioning the function name. This has been fixed - // in Chrome 42. Relax this test there. - // This affects our Android 5.0 & Yandex.Browser testing. - var msg = Array.prototype.join.call( arguments, " " ), - oldChromium = false; - if ( /chrome/i.test( navigator.userAgent ) ) { - oldChromium = parseInt( - navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ], 10 ) < 42; - } - if ( oldChromium ) { - assert.ok( /(?:barf|undefined)/.test( msg ), "Message (weak assertion): " + msg ); - } else { - assert.ok( /barf/.test( msg ), "Message: " + msg ); - } + var msg = Array.prototype.join.call( arguments, " " ); + assert.ok( /barf/.test( msg ), "Message: " + msg ); }; + jQuery.when( defer.then( function() { @@ -613,8 +598,7 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook", func defer.resolve(); } ); -// Test fails in IE9 but is skipped there because console is not active -QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook with stack hooks", function( assert ) { +QUnit.test( "jQuery.Deferred.exceptionHook with stack hooks", function( assert ) { assert.expect( 2 ); @@ -632,26 +616,11 @@ QUnit[ window.console ? "test" : "skip" ]( "jQuery.Deferred.exceptionHook with s }; window.console.warn = function() { - - // Support: Chrome <=41 only - // Some Chrome versions newer than 30 but older than 42 display the "undefined is - // not a function" error, not mentioning the function name. This has been fixed - // in Chrome 42. Relax this test there. - // This affects our Android 5.0 & Yandex.Browser testing. - var msg = Array.prototype.join.call( arguments, " " ), - oldChromium = false; - if ( /chrome/i.test( navigator.userAgent ) ) { - oldChromium = parseInt( - navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ], 10 ) < 42; - } - if ( oldChromium ) { - assert.ok( /(?:cough_up_hairball|undefined)/.test( msg ), - "Function mentioned (weak assertion): " + msg ); - } else { - assert.ok( /cough_up_hairball/.test( msg ), "Function mentioned: " + msg ); - } + var msg = Array.prototype.join.call( arguments, " " ); + assert.ok( /cough_up_hairball/.test( msg ), "Function mentioned: " + msg ); assert.ok( /NO STACK FOR YOU/.test( msg ), "Stack trace included: " + msg ); }; + defer.then( function() { jQuery.cough_up_hairball(); } ).then( null, function( ) { @@ -825,11 +794,7 @@ QUnit.test( "jQuery.when(nonThenable) - like Promise.resolve", function( assert assert.expect( 44 ); - var - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - defaultContext = ( function getDefaultContext() { return this; } ).call(), + var defaultContext = ( function getDefaultContext() { return this; } )(), done = assert.async( 20 ); @@ -884,9 +849,7 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) { var customToStringThen = { then: function( onFulfilled ) { - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - onFulfilled.call(); + onFulfilled(); } }; if ( typeof Symbol === "function" ) { @@ -947,9 +910,7 @@ QUnit.test( "jQuery.when(thenable) - like Promise.resolve", function( assert ) { }, numCases = Object.keys( willSucceed ).length + Object.keys( willError ).length, - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - defaultContext = ( function getDefaultContext() { return this; } ).call(), + defaultContext = ( function getDefaultContext() { return this; } )(), done = assert.async( numCases * 2 ); @@ -1027,9 +988,7 @@ QUnit.test( "jQuery.when(a, b) - like Promise.all", function( assert ) { rejectedStandardPromise: true }, - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - defaultContext = ( function getDefaultContext() { return this; } ).call(), + defaultContext = ( function getDefaultContext() { return this; } )(), done = assert.async( 98 ); diff --git a/test/unit/deprecated.js b/test/unit/deprecated.js index d8b5a518148..9ebdb466d3f 100644 --- a/test/unit/deprecated.js +++ b/test/unit/deprecated.js @@ -159,9 +159,9 @@ QUnit.test( "jQuery.parseJSON", function( assert ) { assert.throws( function() { var result = jQuery.parseJSON( "0101" ); - // Support: IE <=9 only + // Support: IE <=9 - 11 only // Ensure base-10 interpretation on browsers that erroneously accept leading-zero numbers - if ( result === 101 ) { + if ( document.documentMode && result === 101 ) { throw new Error( "close enough" ); } }, null, "Leading-zero number raises an error or is parsed as decimal" ); diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index 23a58523cfe..4a3ad5ecb8e 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -687,19 +687,7 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) { .css( { position: "relative" } ), $boxes = jQuery( [ plainBox[ 0 ], contentBox[ 0 ], borderBox[ 0 ], relativeBorderBox[ 0 ] ] - ).appendTo( parent ), - - // Support: IE 9 only - // Computed width seems to report content width even with "box-sizing: border-box", and - // "overflow: scroll" actually _shrinks_ the element (gh-3699). - borderBoxLoss = - borderBox.clone().css( { overflow: "auto" } ).appendTo( parent )[ 0 ].offsetWidth - - borderBox[ 0 ].offsetWidth; - - if ( borderBoxLoss > 0 ) { - borderBox[ 0 ].style.width = ( size + borderBoxLoss ) + "px"; - borderBox[ 0 ].style.height = ( size + borderBoxLoss ) + "px"; - } + ).appendTo( parent ); for ( i = 0; i < 3; i++ ) { if ( i === 1 ) { @@ -758,10 +746,9 @@ QUnit.test( "outerWidth/Height for table cells and textarea with border-box in I $secondTh = jQuery( "" ), $thirdTh = jQuery( "" ), - // Support: Firefox 63, Edge 16-17, Android 8, iOS 7-11 - // These browsers completely ignore the border-box and height settings - // The computed height is instead just line-height + border - // Either way, what we're doing in css.js is correct + // Most browsers completely ignore the border-box and height settings. + // The computed height is instead just line-height + border. + // Either way, what we're doing in css.js is correct. $td = jQuery( "text" ), $tbody = jQuery( "" ).appendTo( $table ), @@ -775,18 +762,7 @@ QUnit.test( "outerWidth/Height for table cells and textarea with border-box in I assert.strictEqual( $firstTh.outerWidth(), 200, "First th has outerWidth 200." ); assert.strictEqual( $secondTh.outerWidth(), 200, "Second th has outerWidth 200." ); assert.strictEqual( $thirdTh.outerWidth(), 200, "Third th has outerWidth 200." ); - - // Support: Android 4.0-4.3 only - // Android Browser disregards td's box-sizing, treating it like it was content-box. - // Unlike in IE, offsetHeight shares the same issue so there's no easy way to workaround - // the issue without incurring high size penalty. Let's at least check we get the size - // as the browser sees it. - if ( /android 4\.[0-3]/i.test( navigator.userAgent ) ) { - assert.ok( [ 30, 32 ].indexOf( $td.outerHeight() ) > -1, - "outerHeight of td with border-box should include padding." ); - } else { - assert.strictEqual( $td.outerHeight(), 30, "outerHeight of td with border-box should include padding." ); - } + assert.strictEqual( $td.outerHeight(), 30, "outerHeight of td with border-box should include padding." ); assert.strictEqual( $textarea.outerHeight(), 6, "outerHeight of textarea with border-box should include padding and border." ); } ); diff --git a/test/unit/effects.js b/test/unit/effects.js index 05fd1283ef0..6b0efa17b7e 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -690,44 +690,35 @@ QUnit.test( "stop()", function( assert ) { this.clock.tick( 100 ); } ); -// In IE9 inside testswarm this test doesn't work properly -( function() { - var type = "test"; - - if ( QUnit.isSwarm && /msie 9\.0/i.test( window.navigator.userAgent ) ) { - type = "skip"; - } - - QUnit[ type ]( "stop() - several in queue", function( assert ) { - assert.expect( 5 ); +QUnit.test( "stop() - several in queue", function( assert ) { + assert.expect( 5 ); - var nw, $foo = jQuery( "#foo" ); + var nw, $foo = jQuery( "#foo" ); - // default duration is 400ms, so 800px ensures we aren't 0 or 1 after 1ms - $foo.hide().css( "width", 800 ); + // default duration is 400ms, so 800px ensures we aren't 0 or 1 after 1ms + $foo.hide().css( "width", 800 ); - $foo.animate( { "width": "show" }, 400, "linear" ); - $foo.animate( { "width": "hide" } ); - $foo.animate( { "width": "show" } ); + $foo.animate( { "width": "show" }, 400, "linear" ); + $foo.animate( { "width": "hide" } ); + $foo.animate( { "width": "show" } ); - this.clock.tick( 1 ); + this.clock.tick( 1 ); - jQuery.fx.tick(); - assert.equal( $foo.queue().length, 3, "3 in the queue" ); + jQuery.fx.tick(); + assert.equal( $foo.queue().length, 3, "3 in the queue" ); - nw = $foo.css( "width" ); - assert.notEqual( parseFloat( nw ), 1, "An animation occurred " + nw ); - $foo.stop(); + nw = $foo.css( "width" ); + assert.notEqual( parseFloat( nw ), 1, "An animation occurred " + nw ); + $foo.stop(); - assert.equal( $foo.queue().length, 2, "2 in the queue" ); - nw = $foo.css( "width" ); - assert.notEqual( parseFloat( nw ), 1, "Stop didn't reset the animation " + nw ); + assert.equal( $foo.queue().length, 2, "2 in the queue" ); + nw = $foo.css( "width" ); + assert.notEqual( parseFloat( nw ), 1, "Stop didn't reset the animation " + nw ); - $foo.stop( true ); + $foo.stop( true ); - assert.equal( $foo.queue().length, 0, "0 in the queue" ); - } ); -} )(); + assert.equal( $foo.queue().length, 0, "0 in the queue" ); +} ); QUnit.test( "stop(clearQueue)", function( assert ) { assert.expect( 4 ); diff --git a/test/unit/event.js b/test/unit/event.js index c7497b9b0f4..62e62f8f6f5 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1414,7 +1414,7 @@ QUnit.test( "Submit event can be stopped (#11049)", function( assert ) { form.remove(); } ); -// Support: iOS 7 - 9 +// Support: iOS <=7 - 12+ // iOS has the window.onbeforeunload field but doesn't support the beforeunload // handler making it impossible to feature-detect the support. QUnit[ /(ipad|iphone|ipod)/i.test( navigator.userAgent ) ? "skip" : "test" ]( @@ -2931,21 +2931,6 @@ QUnit.test( "trigger('click') on radio passes extra params", function( assert ) $radio.trigger( "click", [ true ] ); } ); -// Support: IE <=9 only -// https://msdn.microsoft.com/en-us/library/hh801223(v=vs.85).aspx -QUnit.test( "VML with special event handlers (trac-7071)", function( assert ) { - assert.expect( 1 ); - - var ns = jQuery( "" ).appendTo( "head" ); - - jQuery( " " ).appendTo( "#form" ); - jQuery( "#form" ).on( "keydown", function() { - assert.ok( true, "no error was thrown" ); - } ); - jQuery( "#oval" ).trigger( "click" ).trigger( "keydown" ); - ns.remove(); -} ); - QUnit.test( "Check order of focusin/focusout events", function( assert ) { assert.expect( 2 ); @@ -2991,7 +2976,7 @@ QUnit.test( "focus-blur order (#12868)", function( assert ) { $text = jQuery( "#text1" ), $radio = jQuery( "#radio1" ), - // Support: IE <=9 - 11+ + // Support: IE <=9 - 11 only // focus and blur events are asynchronous; this is the resulting mess. // The browser window must be topmost for this to work properly!! done = assert.async(); @@ -3052,7 +3037,7 @@ QUnit.test( "native-backed events preserve trigger data (gh-1741, gh-4139)", fun data = [ "arg1", "arg2" ], slice = data.slice, - // Support: IE <=9 - 11+ + // Support: IE <=9 - 11 only // focus and blur events are asynchronous; this is the resulting mess. // The browser window must be topmost for this to work properly!! done = assert.async(); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index b0d3e3a884a..3c19f2e10cf 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -511,18 +511,6 @@ QUnit.test( "Tag name processing respects the HTML Standard (gh-2005)", function } function assertSpecialCharsSupport( method, characters ) { - // Support: Android 4.4 only - // Chromium < 35 incorrectly upper-cases µ; Android 4.4 uses such a version by default - // (and its WebView, being un-updatable, will use it for eternity) so we need to blacklist - // that one for the tests to pass. - if ( characters === "µ" && /chrome/i.test( navigator.userAgent ) && - navigator.userAgent.match( /chrome\/(\d+)/i )[ 1 ] < 35 ) { - assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" ); - assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" ); - assert.ok( true, "This Chromium version upper-cases µ incorrectly; skip test" ); - return; - } - var child, codepoint = characters.charCodeAt( 0 ).toString( 16 ).toUpperCase(), description = characters.length === 1 ? @@ -592,28 +580,7 @@ QUnit.test( "append(xml)", function( assert ) { var xmlDoc, xml1, xml2; function createXMLDoc() { - - // Initialize DOM based upon latest installed MSXML or Netscape - var elem, n, len, - aActiveX = - [ "MSXML6.DomDocument", - "MSXML3.DomDocument", - "MSXML2.DomDocument", - "MSXML.DomDocument", - "Microsoft.XmlDom" ]; - - if ( document.implementation && "createDocument" in document.implementation ) { - return document.implementation.createDocument( "", "", null ); - } else { - - // IE - for ( n = 0, len = aActiveX.length; n < len; n++ ) { - try { - elem = new window.ActiveXObject( aActiveX[ n ] ); - return elem; - } catch ( _ ) {} - } - } + return document.implementation.createDocument( "", "", null ); } xmlDoc = createXMLDoc(); @@ -1798,7 +1765,7 @@ QUnit.test( "html(Function)", function( assert ) { } ); QUnit[ - // Support: Edge 16-18+ + // Support: Edge 16 - 18 only // Edge sometimes doesn't execute module scripts so skip the test there. ( QUnit.moduleTypeSupported && !/edge\//i.test( navigator.userAgent ) ) ? "test" : @@ -1826,7 +1793,7 @@ QUnit[ } ); QUnit[ - // Support: IE 9-11 only, Android 4.0-4.4 only, iOS 7-10 only + // Support: IE 9 - 11 only, iOS <=7 - 10 only // `nomodule` scripts should be executed by legacy browsers only. // iOS 10 supports `