diff --git a/.github/workflows/browser-tests.yml b/.github/workflows/browser-tests.yml index 173d6b1a..b408bb58 100644 --- a/.github/workflows/browser-tests.yml +++ b/.github/workflows/browser-tests.yml @@ -47,7 +47,6 @@ jobs: npm run pretest npm run test:unit -- -b ${{ matrix.BROWSER }} -h \ --jquery-migrate ${{ matrix.MIGRATE_VERSION }} \ - --jquery git --jquery git.min --jquery git.slim --jquery git.slim.min \ --jquery 3.x-git --jquery 3.x-git.min --jquery 3.x-git.slim --jquery 3.x-git.slim.min \ --jquery 3.7.1 --jquery 3.7.1.slim \ --jquery 3.6.4 --jquery 3.5.1 --jquery 3.4.1 \ @@ -84,7 +83,6 @@ jobs: run: | npm run test:ie -- ^ --jquery-migrate ${{ env.MIGRATE_VERSION }} ^ - --jquery git --jquery git.min --jquery git.slim --jquery git.slim.min ^ --jquery 3.x-git --jquery 3.x-git.min --jquery 3.x-git.slim --jquery 3.x-git.slim.min ^ --jquery 3.7.1 --jquery 3.7.1.slim ^ --jquery 3.6.4 --jquery 3.5.1 --jquery 3.4.1 ^ @@ -120,7 +118,6 @@ jobs: run: | npm run test:safari -- \ --jquery-migrate ${{ env.MIGRATE_VERSION }} \ - --jquery git --jquery git.min --jquery git.slim --jquery git.slim.min \ --jquery 3.x-git --jquery 3.x-git.min --jquery 3.x-git.slim --jquery 3.x-git.slim.min \ --jquery 3.7.1 --jquery 3.7.1.slim \ --jquery 3.6.4 --jquery 3.5.1 --jquery 3.4.1 \ diff --git a/.github/workflows/browserstack-git.yml b/.github/workflows/browserstack-git.yml deleted file mode 100644 index e712ad50..00000000 --- a/.github/workflows/browserstack-git.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Browserstack (Core git) - -on: - push: - branches: - - main - # Once a week every Tuesday - schedule: - - cron: "42 1 * * 2" - -jobs: - test: - runs-on: ubuntu-latest - environment: browserstack - env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - NODE_VERSION: 20.x - name: ${{ matrix.BROWSER }} - concurrency: - group: ${{ matrix.BROWSER }} - ${{ github.sha }} - timeout-minutes: 30 - strategy: - fail-fast: false - matrix: - BROWSER: - - 'IE_11' - - 'Safari_latest' - - 'Safari_latest-1' - - 'Chrome_latest' - - 'Chrome_latest-1' - - 'Opera_latest' - - 'Edge_latest' - - 'Edge_latest-1' - - 'Firefox_latest' - - 'Firefox_latest-1' - - 'Firefox_115' - - '__iOS_18' - - '__iOS_17' - - '__iOS_16' - steps: - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-npm-lock-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node-${{ env.NODE_VERSION }}-npm-lock- - - - name: Install dependencies - run: npm install - - - name: Pretest script - run: npm run pretest - - - name: Test - run: | - npm run test:unit -- \ - -v --browserstack "${{ matrix.BROWSER }}" \ - --jquery-migrate dev --jquery-migrate min \ - --jquery git --jquery git.min --jquery git.slim --jquery git.slim.min \ - --run-id ${{ github.run_id }} \ - --retries 3 --hard-retries 1 diff --git a/.github/workflows/browserstack-3.x.yml b/.github/workflows/browserstack.yml similarity index 98% rename from .github/workflows/browserstack-3.x.yml rename to .github/workflows/browserstack.yml index f60b85f5..8d8f9e86 100644 --- a/.github/workflows/browserstack-3.x.yml +++ b/.github/workflows/browserstack.yml @@ -1,4 +1,4 @@ -name: Browserstack (Core 3.x) +name: Browserstack on: push: diff --git a/.github/workflows/filestash.yml b/.github/workflows/filestash.yml index 906f15e1..a70d93a4 100644 --- a/.github/workflows/filestash.yml +++ b/.github/workflows/filestash.yml @@ -47,5 +47,5 @@ jobs: - name: Upload to Filestash run: | - rsync dist/jquery-migrate.js filestash@"${{ secrets.FILESTASH_SERVER }}":jquery-migrate-git.js - rsync dist/jquery-migrate.min.js filestash@"${{ secrets.FILESTASH_SERVER }}":jquery-migrate-git.min.js + rsync dist/jquery-migrate.js filestash@"${{ secrets.FILESTASH_SERVER }}":jquery-migrate-3.x-git.js + rsync dist/jquery-migrate.min.js filestash@"${{ secrets.FILESTASH_SERVER }}":jquery-migrate-3.x-git.min.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb18176c..69865b1d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,7 @@ Make sure you have reproduced the bug with all browser extensions and add-ons di ### Try the latest version of jQuery Migrate -Bugs in old versions of jQuery Migrate may have already been fixed. In order to avoid reporting known issues, make sure you are always testing against the [latest build](https://releases.jquery.com/git/jquery-migrate-git.js). We cannot fix bugs in older released files, if a bug has been fixed in a subsequent version of jQuery Migrate the site should upgrade. +Bugs in old versions of jQuery Migrate may have already been fixed. In order to avoid reporting known issues, make sure you are always testing against the [latest build](https://releases.jquery.com/git/jquery-migrate-3.x-git.js). We cannot fix bugs in older released files, if a bug has been fixed in a subsequent version of jQuery Migrate the site should upgrade. ### Simplify the test case diff --git a/README.md b/README.md index 5512c8e4..bd615a60 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,14 @@ That way you can spot and fix what otherwise would have been errors, until you n The following table indicates which jQuery Migrate versions can be used with which jQuery versions: -| jQuery version | jQuery Migrate version | -|----------------|-------------------------| -| 1.x | 1.x | -| 2.x | 1.x | -| 3.x | 3.x / 4.x[1] | -| 4.x | 3.x / 4.x[1] | +| jQuery version | jQuery Migrate version | +|----------------|------------------------| +| 1.x | 1.x | +| 2.x | 1.x | +| 3.x | 3.x | +| 4.x | 4.x | -[1] NOTE: jQuery Migrate 4.x only supports the same browser as jQuery 4.x does. If you need to support Edge Legacy, Internet Explorer 9-10 or iOS 7+ (and not just 3 latest versions), use jQuery Migrate 3.x. +Each jQuery Migrate version supports the same browsers that the jQuery version used with it. ## Usage @@ -40,7 +40,7 @@ The production build is minified and does not generate console warnings. It will | Debugging enabled |
✓
| | | Minified | |✓
| | Latest release (*may be hotlinked if desired*) | [jquery-migrate-3.5.2.js](https://code.jquery.com/jquery-migrate-3.5.2.js) | [jquery-migrate-3.5.2.min.js](https://code.jquery.com/jquery-migrate-3.5.2.min.js) | -| \* Latest work-in-progress build | [jquery-migrate-git.js](https://releases.jquery.com/git/jquery-migrate-git.js) | [jquery-migrate-git.min.js](https://releases.jquery.com/git/jquery-migrate-git.min.js) | +| \* Latest work-in-progress build | [jquery-migrate-3.x-git.js](https://releases.jquery.com/git/jquery-migrate-3.x-git.js) | [jquery-migrate-3.x-git.min.js](https://releases.jquery.com/git/jquery-migrate-3.x-git.min.js) | \* **Work-in-progress build:** Although this file represents the most recent updates to the plugin, it may not have been thoroughly tested. We do not recommend using this file on production sites since it may be unstable; use the released production version instead. diff --git a/src/jquery/ajax.js b/src/jquery/ajax.js index 91555749..9c2bf679 100644 --- a/src/jquery/ajax.js +++ b/src/jquery/ajax.js @@ -1,4 +1,3 @@ -import { jQueryVersionSince } from "../compareVersions.js"; import { migrateWarn, migratePatchAndWarnFunc, migratePatchFunc } from "../main.js"; // Support jQuery slim which excludes the ajax module @@ -8,8 +7,7 @@ var oldAjax = jQuery.ajax, oldCallbacks = [], guid = "migrate-" + Date.now(), origJsonpCallback = jQuery.ajaxSettings.jsonpCallback, - rjsonp = /(=)\?(?=&|$)|\?\?/, - rquery = /\?/; + rjsonp = /(=)\?(?=&|$)|\?\?/; migratePatchFunc( jQuery, "ajax", function() { var jQXHR = oldAjax.apply( this, arguments ); @@ -45,120 +43,23 @@ jQuery.ajaxSetup( { // Register this prefilter before the jQuery one. Otherwise, a promoted // request is transformed into one with the script dataType, and we can't // catch it anymore. -if ( jQueryVersionSince( "4.0.0" ) ) { - - // Code mostly from: - // https://github.com/jquery/jquery/blob/fa0058af426c4e482059214c29c29f004254d9a1/src/ajax/jsonp.js#L20-L97 - jQuery.ajaxPrefilter( "+json", function( s, originalSettings, jqXHR ) { - - if ( !jQuery.migrateIsPatchEnabled( "jsonp-promotion" ) ) { - return; - } - - var callbackName, overwritten, responseContainer, - jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? - "url" : - typeof s.data === "string" && - ( s.contentType || "" ) - .indexOf( "application/x-www-form-urlencoded" ) === 0 && - rjsonp.test( s.data ) && "data" - ); - - // Handle iff the expected data type is "jsonp" or we have a parameter to set - if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { - migrateWarn( "jsonp-promotion", "JSON-to-JSONP auto-promotion is deprecated" ); - - // Get callback name, remembering preexisting value associated with it - callbackName = s.jsonpCallback = typeof s.jsonpCallback === "function" ? - s.jsonpCallback() : - s.jsonpCallback; - - // Insert callback into url or form data - if ( jsonProp ) { - s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); - } else if ( s.jsonp !== false ) { - s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; - } - - // Use data converter to retrieve json after script execution - s.converters[ "script json" ] = function() { - if ( !responseContainer ) { - jQuery.error( callbackName + " was not called" ); - } - return responseContainer[ 0 ]; - }; - - // Force json dataType - s.dataTypes[ 0 ] = "json"; - - // Install callback - overwritten = window[ callbackName ]; - window[ callbackName ] = function() { - responseContainer = arguments; - }; - - // Clean-up function (fires after converters) - jqXHR.always( function() { - - // If previous value didn't exist - remove it - if ( overwritten === undefined ) { - jQuery( window ).removeProp( callbackName ); - - // Otherwise restore preexisting value - } else { - window[ callbackName ] = overwritten; - } - - // Save back as free - if ( s[ callbackName ] ) { - - // Make sure that re-using the options doesn't screw things around - s.jsonpCallback = originalSettings.jsonpCallback; - - // Save the callback name for future use - oldCallbacks.push( callbackName ); - } - - // Call if it was a function and we have a response - if ( responseContainer && typeof overwritten === "function" ) { - overwritten( responseContainer[ 0 ] ); - } - - responseContainer = overwritten = undefined; - } ); - - // Delegate to script - return "script"; - } - } ); -} else { - - // jQuery <4 already contains this prefixer; don't duplicate the whole logic, - // but only enough to know when to warn. - jQuery.ajaxPrefilter( "+json", function( s ) { - - if ( !jQuery.migrateIsPatchEnabled( "jsonp-promotion" ) ) { - return; - } - - // Warn if JSON-to-JSONP auto-promotion happens. - if ( s.jsonp !== false && ( rjsonp.test( s.url ) || - typeof s.data === "string" && - ( s.contentType || "" ) - .indexOf( "application/x-www-form-urlencoded" ) === 0 && - rjsonp.test( s.data ) - ) ) { - migrateWarn( "jsonp-promotion", "JSON-to-JSONP auto-promotion is deprecated" ); - } - } ); -} +// jQuery <4 already contains this prefixer; don't duplicate the whole logic, +// but only enough to know when to warn. +jQuery.ajaxPrefilter( "+json", function( s ) { + if ( !jQuery.migrateIsPatchEnabled( "jsonp-promotion" ) ) { + return; + } -// Don't trigger the above logic in jQuery >=4 by default as the JSON-to-JSONP -// auto-promotion behavior is gone in jQuery 4.0 and as it has security implications, -// we don't want to restore the legacy behavior by default. -if ( jQueryVersionSince( "4.0.0" ) ) { - jQuery.migrateDisablePatches( "jsonp-promotion" ); -} + // Warn if JSON-to-JSONP auto-promotion happens. + if ( s.jsonp !== false && ( rjsonp.test( s.url ) || + typeof s.data === "string" && + ( s.contentType || "" ) + .indexOf( "application/x-www-form-urlencoded" ) === 0 && + rjsonp.test( s.data ) + ) ) { + migrateWarn( "jsonp-promotion", "JSON-to-JSONP auto-promotion is deprecated" ); + } +} ); } diff --git a/src/jquery/attributes.js b/src/jquery/attributes.js index f76b1499..be029948 100644 --- a/src/jquery/attributes.js +++ b/src/jquery/attributes.js @@ -1,5 +1,4 @@ import { migratePatchFunc, migrateWarn } from "../main.js"; -import { jQueryVersionSince } from "../compareVersions.js"; var oldRemoveAttr = jQuery.fn.removeAttr, oldJQueryAttr = jQuery.attr, @@ -36,15 +35,6 @@ jQuery.each( booleans.split( "|" ), function( _i, name ) { migrateWarn( "boolean-attributes", "Boolean attribute '" + name + "' value is different from its lowercased name" ); - - // jQuery <4 attr hooks setup is complex: there are attr - // hooks, bool hooks and selector attr handles. Only - // implement the logic in jQuery >=4 where it's missing - // and there are only attr hooks. - if ( jQueryVersionSince( "4.0.0" ) ) { - return name.toLowerCase(); - } - return null; } } @@ -72,12 +62,12 @@ jQuery.each( booleans.split( "|" ), function( _i, name ) { } return name; } - } else if ( !jQueryVersionSince( "4.0.0" ) ) { + } else { // jQuery <4 uses a private `boolHook` for the boolean attribute // setter. It's only activated if `attrHook` is not set, but we set - // it here in Migrate. Since we cannot access it, let's just repeat - // its contents here. + // it here in Migrate so jQuery would not use it. Since we cannot + // access it, let's just repeat its contents here. if ( value === false ) { // Remove boolean attributes when set to false diff --git a/src/jquery/core.js b/src/jquery/core.js index 7d92fefd..26d47a0f 100644 --- a/src/jquery/core.js +++ b/src/jquery/core.js @@ -1,24 +1,8 @@ import { jQueryVersionSince } from "../compareVersions.js"; -import { - migratePatchFunc, - migrateWarn, - migratePatchAndWarnFunc, - migrateWarnProp -} from "../main.js"; +import { migratePatchAndWarnFunc } from "../main.js"; import "../disablePatches.js"; -var findProp, - arr = [], - push = arr.push, - slice = arr.slice, - sort = arr.sort, - splice = arr.splice, - class2type = {}, - oldInit = jQuery.fn.init, - oldFind = jQuery.find, - - rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, - rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g, +var class2type = {}, // Require that the "whitespace run" starts from a non-whitespace // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. @@ -37,68 +21,6 @@ function isFunction( obj ) { typeof obj.item !== "function"; } -migratePatchFunc( jQuery.fn, "init", function( arg1 ) { - var args = Array.prototype.slice.call( arguments ); - - if ( jQuery.migrateIsPatchEnabled( "selector-empty-id" ) && - typeof arg1 === "string" && arg1 === "#" ) { - - // JQuery( "#" ) is a bogus ID selector, but it returned an empty set - // before jQuery 3.0 - migrateWarn( "selector-empty-id", "jQuery( '#' ) is not a valid selector" ); - args[ 0 ] = []; - } - - return oldInit.apply( this, args ); -}, "selector-empty-id" ); - -// This is already done in Core but the above patch will lose this assignment -// so we need to redo it. It doesn't matter whether the patch is enabled or not -// as the method is always going to be a Migrate-created wrapper. -jQuery.fn.init.prototype = jQuery.fn; - -migratePatchFunc( jQuery, "find", function( selector ) { - var args = Array.prototype.slice.call( arguments ); - - // Support: PhantomJS 1.x - // String#match fails to match when used with a //g RegExp, only on some strings - if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { - - // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 - // First see if qS thinks it's a valid selector, if so avoid a false positive - try { - window.document.querySelector( selector ); - } catch ( err1 ) { - - // Didn't *look* valid to qSA, warn and try quoting what we think is the value - selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { - return "[" + attr + op + "\"" + value + "\"]"; - } ); - - // If the regexp *may* have created an invalid selector, don't update it - // Note that there may be false alarms if selector uses jQuery extensions - try { - window.document.querySelector( selector ); - migrateWarn( "selector-hash", - "Attribute selector with '#' must be quoted: " + args[ 0 ] ); - args[ 0 ] = selector; - } catch ( err2 ) { - migrateWarn( "selector-hash", - "Attribute selector with '#' was not fixed: " + args[ 0 ] ); - } - } - } - - return oldFind.apply( this, args ); -}, "selector-hash" ); - -// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) -for ( findProp in oldFind ) { - if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { - jQuery.find[ findProp ] = oldFind[ findProp ]; - } -} - // The number of elements contained in the matched element set migratePatchAndWarnFunc( jQuery.fn, "size", function() { return this.length; @@ -176,11 +98,10 @@ if ( jQueryVersionSince( "3.3.0" ) ) { }, "type", "jQuery.type is deprecated" ); - migratePatchAndWarnFunc( jQuery, "isFunction", - function( obj ) { - return typeof obj === "function"; - }, "isFunction", - "jQuery.isFunction() is deprecated" ); + migratePatchAndWarnFunc( jQuery, "isFunction", function( obj ) { + return isFunction( obj ); + }, "isFunction", + "jQuery.isFunction() is deprecated" ); migratePatchAndWarnFunc( jQuery, "isWindow", function( obj ) { @@ -193,46 +114,7 @@ if ( jQueryVersionSince( "3.3.0" ) ) { // arguments. // jQuery.proxy is deprecated to promote standards (specifically Function#bind) // However, it is not slated for removal any time soon - migratePatchAndWarnFunc( jQuery, "proxy", - function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, "proxy", - "jQuery.proxy() is deprecated" - ); - -} - -if ( jQueryVersionSince( "4.0.0" ) ) { + migratePatchAndWarnFunc( jQuery, "proxy", jQuery.proxy, + "proxy", "DEPRECATED: jQuery.proxy()" ); - // `push`, `sort` & `splice` are used internally by jQuery <4, so we only - // warn in jQuery 4+. - migrateWarnProp( jQuery.fn, "push", push, "push", - "jQuery.fn.push() is deprecated and removed; use .add or convert to an array" ); - migrateWarnProp( jQuery.fn, "sort", sort, "sort", - "jQuery.fn.sort() is deprecated and removed; convert to an array before sorting" ); - migrateWarnProp( jQuery.fn, "splice", splice, "splice", - "jQuery.fn.splice() is deprecated and removed; use .slice or .not with .eq" ); } diff --git a/src/jquery/css.js b/src/jquery/css.js index 2ae10feb..f06853fc 100644 --- a/src/jquery/css.js +++ b/src/jquery/css.js @@ -2,7 +2,7 @@ import { jQueryVersionSince } from "../compareVersions.js"; import { migrateWarn, migratePatchFunc } from "../main.js"; import { camelCase } from "../utils.js"; -var origFnCss, internalCssNumber, +var origFnCss, internalSwapCall = false, ralphaStart = /^[a-z]/, @@ -80,71 +80,6 @@ if ( jQueryVersionSince( "3.4.0" ) && typeof Proxy !== "undefined" ) { } ); } -// In jQuery >=4 where jQuery.cssNumber is missing fill it with the latest 3.x version: -// https://github.com/jquery/jquery/blob/3.7.1/src/css.js#L216-L246 -// This way, number values for the CSS properties below won't start triggering -// Migrate warnings when jQuery gets updated to >=4.0.0 (gh-438). -if ( jQueryVersionSince( "4.0.0" ) ) { - - // We need to keep this as a local variable as we need it internally - // in a `jQuery.fn.css` patch and this usage shouldn't warn. - internalCssNumber = { - animationIterationCount: true, - aspectRatio: true, - borderImageSlice: true, - columnCount: true, - flexGrow: true, - flexShrink: true, - fontWeight: true, - gridArea: true, - gridColumn: true, - gridColumnEnd: true, - gridColumnStart: true, - gridRow: true, - gridRowEnd: true, - gridRowStart: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - scale: true, - widows: true, - zIndex: true, - zoom: true, - - // SVG-related - fillOpacity: true, - floodOpacity: true, - stopOpacity: true, - strokeMiterlimit: true, - strokeOpacity: true - }; - - if ( typeof Proxy !== "undefined" ) { - jQuery.cssNumber = new Proxy( internalCssNumber, { - get: function() { - migrateWarn( "css-number", "jQuery.cssNumber is deprecated" ); - return Reflect.get.apply( this, arguments ); - }, - set: function() { - migrateWarn( "css-number", "jQuery.cssNumber is deprecated" ); - return Reflect.set.apply( this, arguments ); - } - } ); - } else { - - // Support: IE 9-11+ - // IE doesn't support proxies, but we still want to restore the legacy - // jQuery.cssNumber there. - jQuery.cssNumber = internalCssNumber; - } -} else { - - // Make `internalCssNumber` defined for jQuery <4 as well as it's needed - // in the `jQuery.fn.css` patch below. - internalCssNumber = jQuery.cssNumber; -} - function isAutoPx( prop ) { // The first test is used to ensure that: @@ -170,9 +105,7 @@ migratePatchFunc( jQuery.fn, "css", function( name, value ) { if ( typeof value === "number" ) { camelName = camelCase( name ); - // Use `internalCssNumber` to avoid triggering our warnings in this - // internal check. - if ( !isAutoPx( camelName ) && !internalCssNumber[ camelName ] ) { + if ( !isAutoPx( camelName ) && !jQuery.cssNumber[ camelName ] ) { migrateWarn( "css-number", "Number-typed values are deprecated for jQuery.fn.css( \"" + name + "\", value )" ); diff --git a/src/jquery/deferred.js b/src/jquery/deferred.js index 7f036efe..bb78cd3e 100644 --- a/src/jquery/deferred.js +++ b/src/jquery/deferred.js @@ -3,7 +3,6 @@ import { migratePatchAndWarnFunc, migrateWarn } from "../main.js"; -import { jQueryVersionSince } from "../compareVersions.js"; // Support jQuery slim which excludes the deferred module in jQuery 4.0+ if ( jQuery.Deferred ) { @@ -80,13 +79,8 @@ Object.defineProperty( jQuery.Deferred, "getStackHook", { get: function() { if ( jQuery.migrateIsPatchEnabled( "deferred-getStackHook" ) ) { - // jQuery 3.x checks `getStackHook` if `getErrorHook` missing; - // don't warn on the getter there. - if ( jQueryVersionSince( "4.0.0" ) ) { - migrateWarn( "deferred-getStackHook", - "jQuery.Deferred.getStackHook is deprecated; " + - "use jQuery.Deferred.getErrorHook" ); - } + // jQuery 3.x checks `getStackHook` if `getErrorHook` is missing, + // so don't warn on the getter. return jQuery.Deferred.getErrorHook; } else { return unpatchedGetStackHookValue; diff --git a/src/jquery/event.js b/src/jquery/event.js index 5a5ea9a1..e7a6c4b8 100644 --- a/src/jquery/event.js +++ b/src/jquery/event.js @@ -96,13 +96,9 @@ jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + function( _i, name ) { // Handle event binding - migratePatchAndWarnFunc( jQuery.fn, name, function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }, - "shorthand-deprecated-v3", - "jQuery.fn." + name + "() event shorthand is deprecated" ); + migratePatchAndWarnFunc( jQuery.fn, name, jQuery.fn[ name ], "shorthand-deprecated-v3", + "DEPRECATED: jQuery.fn." + name + "() event shorthand" ); + } ); // Trigger "ready" event only once, on document ready @@ -118,20 +114,15 @@ jQuery.event.special.ready = { } }; -migratePatchAndWarnFunc( jQuery.fn, "bind", function( types, data, fn ) { - return this.on( types, null, data, fn ); -}, "pre-on-methods", "jQuery.fn.bind() is deprecated" ); -migratePatchAndWarnFunc( jQuery.fn, "unbind", function( types, fn ) { - return this.off( types, null, fn ); -}, "pre-on-methods", "jQuery.fn.unbind() is deprecated" ); -migratePatchAndWarnFunc( jQuery.fn, "delegate", function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); -}, "pre-on-methods", "jQuery.fn.delegate() is deprecated" ); -migratePatchAndWarnFunc( jQuery.fn, "undelegate", function( selector, types, fn ) { - return arguments.length === 1 ? - this.off( selector, "**" ) : - this.off( types, selector || "**", fn ); -}, "pre-on-methods", "jQuery.fn.undelegate() is deprecated" ); +migratePatchAndWarnFunc( jQuery.fn, "bind", jQuery.fn.bind, + "pre-on-methods", "jQuery.fn.bind() is deprecated" ); +migratePatchAndWarnFunc( jQuery.fn, "unbind", jQuery.fn.unbind, + "pre-on-methods", "jQuery.fn.unbind() is deprecated" ); +migratePatchAndWarnFunc( jQuery.fn, "delegate", jQuery.fn.delegate, + "pre-on-methods", "jQuery.fn.delegate() is deprecated" ); +migratePatchAndWarnFunc( jQuery.fn, "undelegate", jQuery.fn.undelegate, + "pre-on-methods", "jQuery.fn.undelegate() is deprecated" ); + migratePatchAndWarnFunc( jQuery.fn, "hover", function( fnOver, fnOut ) { return this.on( "mouseenter", fnOver ).on( "mouseleave", fnOut || fnOver ); }, "pre-on-methods", "jQuery.fn.hover() is deprecated" ); diff --git a/src/jquery/selector.js b/src/jquery/selector.js index 44237d30..c1625a12 100644 --- a/src/jquery/selector.js +++ b/src/jquery/selector.js @@ -1,6 +1,75 @@ import { jQueryVersionSince } from "../compareVersions.js"; import { migratePatchFunc, migrateWarnProp, migrateWarn } from "../main.js"; +var findProp, + oldInit = jQuery.fn.init, + oldFind = jQuery.find, + + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +migratePatchFunc( jQuery.fn, "init", function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( jQuery.migrateIsPatchEnabled( "selector-empty-id" ) && + typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set + // before jQuery 3.0 + migrateWarn( "selector-empty-id", "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}, "selector-empty-id" ); + +// This is already done in Core but the above patch will lose this assignment +// so we need to redo it. It doesn't matter whether the patch is enabled or not +// as the method is always going to be a Migrate-created wrapper. +jQuery.fn.init.prototype = jQuery.fn; + +migratePatchFunc( jQuery, "find", function( selector ) { + var args = Array.prototype.slice.call( arguments ); + + // Support: PhantomJS 1.x + // String#match fails to match when used with a //g RegExp, only on some strings + if ( typeof selector === "string" && rattrHashTest.test( selector ) ) { + + // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0 + // First see if qS thinks it's a valid selector, if so avoid a false positive + try { + window.document.querySelector( selector ); + } catch ( err1 ) { + + // Didn't *look* valid to qSA, warn and try quoting what we think is the value + selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) { + return "[" + attr + op + "\"" + value + "\"]"; + } ); + + // If the regexp *may* have created an invalid selector, don't update it + // Note that there may be false alarms if selector uses jQuery extensions + try { + window.document.querySelector( selector ); + migrateWarn( "selector-hash", + "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "selector-hash", + "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}, "selector-hash" ); + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + // Now jQuery.expr.pseudos is the standard incantation migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, "expr-pre-pseudos", "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos" ); diff --git a/src/main.js b/src/main.js index ca6ce5c7..909b6203 100644 --- a/src/main.js +++ b/src/main.js @@ -10,10 +10,10 @@ if ( !window.console || !window.console.log ) { return; } -// Need jQuery 3.x-4.x and no older Migrate loaded +// Need jQuery 3.x and no older Migrate loaded if ( !jQuery || !jQueryVersionSince( "3.0.0" ) || - jQueryVersionSince( "5.0.0" ) ) { - window.console.log( "JQMIGRATE: jQuery 3.x-4.x REQUIRED" ); + jQueryVersionSince( "4.0.0" ) ) { + window.console.log( "JQMIGRATE: jQuery 3.x REQUIRED" ); } if ( jQuery.migrateWarnings ) { window.console.log( "JQMIGRATE: Migrate plugin loaded multiple times" ); diff --git a/test/data/ajax-jsonp-callback-name.html b/test/data/ajax-jsonp-callback-name.html index 2d10331a..fd9766b9 100644 --- a/test/data/ajax-jsonp-callback-name.html +++ b/test/data/ajax-jsonp-callback-name.html @@ -7,7 +7,7 @@