diff --git a/src/jquery/event.js b/src/jquery/event.js index c0cce65..071c23d 100644 --- a/src/jquery/event.js +++ b/src/jquery/event.js @@ -5,6 +5,7 @@ import { migrateWarnProp } from "../main.js"; import "../disablePatches.js"; +import { patchProto } from "../utils.js"; var oldLoad = jQuery.fn.load, oldEventAdd = jQuery.event.add, @@ -136,3 +137,11 @@ migratePatchAndWarnFunc( jQuery.fn, "undelegate", function( selector, types, fn migratePatchAndWarnFunc( jQuery.fn, "hover", function( fnOver, fnOut ) { return this.on( "mouseenter", fnOver ).on( "mouseleave", fnOut || fnOver ); }, "pre-on-methods", "jQuery.fn.hover() is deprecated" ); + +// We can apply the patch unconditionally here as in the `3.x` line the API +// inherits from `Object.prototype` even without a patch and `migrateWarn` +// inside `patchProto` will already silence warnings if the patch gets disabled. +patchProto( jQuery.event.special, { + warningId: "event-special-null-proto", + apiName: "jQuery.event.special" +} ); diff --git a/test/unit/jquery/event.js b/test/unit/jquery/event.js index ee5b794..1e34774 100644 --- a/test/unit/jquery/event.js +++ b/test/unit/jquery/event.js @@ -190,3 +190,27 @@ TestManager.runIframeTest( "Load within a ready handler", "event-lateload.html", JSON.stringify( jQuery.migrateWarnings ) ); assert.ok( /load/.test( jQuery.migrateWarnings[ 0 ] ), "message ok" ); } ); + +QUnit.test( "jQuery.event.special: properties from Object.prototype", function( assert ) { + assert.expect( 4 ); + + try { + expectNoWarning( assert, "Regular properties", function() { + jQuery.event.special.fakeevent = {}; + + // eslint-disable-next-line no-unused-expressions + jQuery.event.special.fakeevent; + } ); + + ( + Object.setPrototypeOf ? expectWarning : expectNoWarning + )( assert, "Properties from Object.prototype", 2, function() { + assert.ok( jQuery.event.special.hasOwnProperty( "fakeevent" ), + "hasOwnProperty works (property present)" ); + assert.ok( !jQuery.event.special.hasOwnProperty( "fakeevent2" ), + "hasOwnProperty works (property missing)" ); + } ); + } finally { + delete jQuery.event.special.fakeevent; + } +} );