2 * jQuery Migrate - v3.0.1 - 2017-09-26
3 * Copyright jQuery Foundation and other contributors
5 * Patched for MediaWiki:
6 * - Qualify the global lookup for 'jQuery' as 'window.jQuery',
7 * because within mw.loader.implement() for 'jquery', the closure
8 * specifies '$' and 'jQuery', which are undefined.
9 * - Add mw.track instrumentation for statistics.
10 * - Disable jQuery.migrateTrace by default. They are slow and
11 * redundant given console.warn() already provides a trace.
13 ;( function( factory
) {
14 if ( typeof define
=== "function" && define
.amd
) {
16 // AMD. Register as an anonymous module.
17 define( [ "jquery" ], window
, factory
);
18 } else if ( typeof module
=== "object" && module
.exports
) {
21 // eslint-disable-next-line no-undef
22 module
.exports
= factory( require( "jquery" ), window
);
26 // PATCH: Qualify jQuery lookup as window.jQuery. --Krinkle
27 factory( window
.jQuery
, window
);
29 } )( function( jQuery
, window
) {
33 jQuery
.migrateVersion
= "3.0.1";
35 /* exported migrateWarn, migrateWarnFunc, migrateWarnProp */
39 var rbadVersions
= /^[12]\./;
42 // IE9 only creates console object when dev tools are first opened
43 // IE9 console is a host object, callable but doesn't have .apply()
44 if ( !window
.console
|| !window
.console
.log
) {
48 // Need jQuery 3.0.0+ and no older Migrate loaded
49 if ( !jQuery
|| rbadVersions
.test( jQuery
.fn
.jquery
) ) {
50 window
.console
.log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" );
52 if ( jQuery
.migrateWarnings
) {
53 window
.console
.log( "JQMIGRATE: Migrate plugin loaded multiple times" );
56 // Show a message on the console so devs know we're active
57 window
.console
.log( "JQMIGRATE: Migrate is installed" +
58 ( jQuery
.migrateMute
? "" : " with logging active" ) +
59 ", version " + jQuery
.migrateVersion
);
65 // List of warnings already given; public read only
66 jQuery
.migrateWarnings
= [];
68 // Set to false to disable traces that appear with warnings
69 if ( jQuery
.migrateTrace
=== undefined ) {
70 // PATCH: Disable extra console.trace() call --Krinkle
71 jQuery
.migrateTrace
= false;
74 // Forget any warnings we've already given; public
75 jQuery
.migrateReset = function() {
77 jQuery
.migrateWarnings
.length
= 0;
80 function migrateWarn( msg
) {
81 var console
= window
.console
;
82 if ( !warnedAbout
[ msg
] ) {
83 warnedAbout
[ msg
] = true;
84 jQuery
.migrateWarnings
.push( msg
);
85 // PATCH: Add instrumentation for statistics --Krinkle
86 if ( window
.mw
&& window
.mw
.track
) {
87 window
.mw
.track( "mw.deprecate", "jquery-migrate" );
89 if ( console
&& console
.warn
&& !jQuery
.migrateMute
) {
90 console
.warn( "JQMIGRATE: " + msg
);
91 if ( jQuery
.migrateTrace
&& console
.trace
) {
98 function migrateWarnProp( obj
, prop
, value
, msg
) {
99 Object
.defineProperty( obj
, prop
, {
106 set: function( newValue
) {
113 function migrateWarnFunc( obj
, prop
, newFunc
, msg
) {
114 obj
[ prop
] = function() {
116 return newFunc
.apply( this, arguments
);
120 if ( window
.document
.compatMode
=== "BackCompat" ) {
122 // JQuery has never supported or tested Quirks Mode
123 migrateWarn( "jQuery is not compatible with Quirks Mode" );
127 var oldInit
= jQuery
.fn
.init
,
128 oldIsNumeric
= jQuery
.isNumeric
,
129 oldFind
= jQuery
.find
,
130 rattrHashTest
= /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
131 rattrHashGlob
= /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;
133 jQuery
.fn
.init = function( arg1
) {
134 var args
= Array
.prototype.slice
.call( arguments
);
136 if ( typeof arg1
=== "string" && arg1
=== "#" ) {
138 // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
139 migrateWarn( "jQuery( '#' ) is not a valid selector" );
143 return oldInit
.apply( this, args
);
145 jQuery
.fn
.init
.prototype = jQuery
.fn
;
147 jQuery
.find = function( selector
) {
148 var args
= Array
.prototype.slice
.call( arguments
);
150 // Support: PhantomJS 1.x
151 // String#match fails to match when used with a //g RegExp, only on some strings
152 if ( typeof selector
=== "string" && rattrHashTest
.test( selector
) ) {
154 // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
155 // First see if qS thinks it's a valid selector, if so avoid a false positive
157 window
.document
.querySelector( selector
);
160 // Didn't *look* valid to qSA, warn and try quoting what we think is the value
161 selector
= selector
.replace( rattrHashGlob
, function( _
, attr
, op
, value
) {
162 return "[" + attr
+ op
+ "\"" + value
+ "\"]";
165 // If the regexp *may* have created an invalid selector, don't update it
166 // Note that there may be false alarms if selector uses jQuery extensions
168 window
.document
.querySelector( selector
);
169 migrateWarn( "Attribute selector with '#' must be quoted: " + args
[ 0 ] );
170 args
[ 0 ] = selector
;
172 migrateWarn( "Attribute selector with '#' was not fixed: " + args
[ 0 ] );
177 return oldFind
.apply( this, args
);
180 // Copy properties attached to original jQuery.find method (e.g. .attr, .isXML)
182 for ( findProp
in oldFind
) {
183 if ( Object
.prototype.hasOwnProperty
.call( oldFind
, findProp
) ) {
184 jQuery
.find
[ findProp
] = oldFind
[ findProp
];
188 // The number of elements contained in the matched element set
189 jQuery
.fn
.size = function() {
190 migrateWarn( "jQuery.fn.size() is deprecated and removed; use the .length property" );
194 jQuery
.parseJSON = function() {
195 migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" );
196 return JSON
.parse
.apply( null, arguments
);
199 jQuery
.isNumeric = function( val
) {
201 // The jQuery 2.2.3 implementation of isNumeric
202 function isNumeric2( obj
) {
203 var realStringObj
= obj
&& obj
.toString();
204 return !jQuery
.isArray( obj
) && ( realStringObj
- parseFloat( realStringObj
) + 1 ) >= 0;
207 var newValue
= oldIsNumeric( val
),
208 oldValue
= isNumeric2( val
);
210 if ( newValue
!== oldValue
) {
211 migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" );
217 migrateWarnFunc( jQuery
, "holdReady", jQuery
.holdReady
,
218 "jQuery.holdReady is deprecated" );
220 migrateWarnFunc( jQuery
, "unique", jQuery
.uniqueSort
,
221 "jQuery.unique is deprecated; use jQuery.uniqueSort" );
223 // Now jQuery.expr.pseudos is the standard incantation
224 migrateWarnProp( jQuery
.expr
, "filters", jQuery
.expr
.pseudos
,
225 "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos" );
226 migrateWarnProp( jQuery
.expr
, ":", jQuery
.expr
.pseudos
,
227 "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos" );
230 var oldAjax
= jQuery
.ajax
;
232 jQuery
.ajax = function( ) {
233 var jQXHR
= oldAjax
.apply( this, arguments
);
235 // Be sure we got a jQXHR (e.g., not sync)
236 if ( jQXHR
.promise
) {
237 migrateWarnFunc( jQXHR
, "success", jQXHR
.done
,
238 "jQXHR.success is deprecated and removed" );
239 migrateWarnFunc( jQXHR
, "error", jQXHR
.fail
,
240 "jQXHR.error is deprecated and removed" );
241 migrateWarnFunc( jQXHR
, "complete", jQXHR
.always
,
242 "jQXHR.complete is deprecated and removed" );
249 var oldRemoveAttr
= jQuery
.fn
.removeAttr
,
250 oldToggleClass
= jQuery
.fn
.toggleClass
,
251 rmatchNonSpace
= /\S+/g;
253 jQuery
.fn
.removeAttr = function( name
) {
256 jQuery
.each( name
.match( rmatchNonSpace
), function( i
, attr
) {
257 if ( jQuery
.expr
.match
.bool
.test( attr
) ) {
258 migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr
);
259 self
.prop( attr
, false );
263 return oldRemoveAttr
.apply( this, arguments
);
266 jQuery
.fn
.toggleClass = function( state
) {
268 // Only deprecating no-args or single boolean arg
269 if ( state
!== undefined && typeof state
!== "boolean" ) {
270 return oldToggleClass
.apply( this, arguments
);
273 migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" );
275 // Toggle entire class name of each element
276 return this.each( function() {
277 var className
= this.getAttribute
&& this.getAttribute( "class" ) || "";
280 jQuery
.data( this, "__className__", className
);
283 // If the element has a class name or if we're passed `false`,
284 // then remove the whole classname (if there was one, the above saved it).
285 // Otherwise bring back whatever was previously saved (if anything),
286 // falling back to the empty string if nothing was stored.
287 if ( this.setAttribute
) {
288 this.setAttribute( "class",
289 className
|| state
=== false ?
291 jQuery
.data( this, "__className__" ) || ""
298 var internalSwapCall
= false;
300 // If this version of jQuery has .swap(), don't false-alarm on internal uses
302 jQuery
.each( [ "height", "width", "reliableMarginRight" ], function( _
, name
) {
303 var oldHook
= jQuery
.cssHooks
[ name
] && jQuery
.cssHooks
[ name
].get;
306 jQuery
.cssHooks
[ name
].get = function() {
309 internalSwapCall
= true;
310 ret
= oldHook
.apply( this, arguments
);
311 internalSwapCall
= false;
318 jQuery
.swap = function( elem
, options
, callback
, args
) {
322 if ( !internalSwapCall
) {
323 migrateWarn( "jQuery.swap() is undocumented and deprecated" );
326 // Remember the old values, and insert the new ones
327 for ( name
in options
) {
328 old
[ name
] = elem
.style
[ name
];
329 elem
.style
[ name
] = options
[ name
];
332 ret
= callback
.apply( elem
, args
|| [] );
334 // Revert the old values
335 for ( name
in options
) {
336 elem
.style
[ name
] = old
[ name
];
342 var oldData
= jQuery
.data
;
344 jQuery
.data = function( elem
, name
, value
) {
347 // Name can be an object, and each entry in the object is meant to be set as data
348 if ( name
&& typeof name
=== "object" && arguments
.length
=== 2 ) {
349 curData
= jQuery
.hasData( elem
) && oldData
.call( this, elem
);
351 for ( var key
in name
) {
352 if ( key
!== jQuery
.camelCase( key
) ) {
353 migrateWarn( "jQuery.data() always sets/gets camelCased names: " + key
);
354 curData
[ key
] = name
[ key
];
356 sameKeys
[ key
] = name
[ key
];
360 oldData
.call( this, elem
, sameKeys
);
365 // If the name is transformed, look for the un-transformed name in the data object
366 if ( name
&& typeof name
=== "string" && name
!== jQuery
.camelCase( name
) ) {
367 curData
= jQuery
.hasData( elem
) && oldData
.call( this, elem
);
368 if ( curData
&& name
in curData
) {
369 migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name
);
370 if ( arguments
.length
> 2 ) {
371 curData
[ name
] = value
;
373 return curData
[ name
];
377 return oldData
.apply( this, arguments
);
380 var oldTweenRun
= jQuery
.Tween
.prototype.run
;
381 var linearEasing = function( pct
) {
385 jQuery
.Tween
.prototype.run = function( ) {
386 if ( jQuery
.easing
[ this.easing
].length
> 1 ) {
388 "'jQuery.easing." + this.easing
.toString() + "' should use only one argument"
391 jQuery
.easing
[ this.easing
] = linearEasing
;
394 oldTweenRun
.apply( this, arguments
);
397 jQuery
.fx
.interval
= jQuery
.fx
.interval
|| 13;
399 // Support: IE9, Android <=4.4
400 // Avoid false positives on browsers that lack rAF
401 if ( window
.requestAnimationFrame
) {
402 migrateWarnProp( jQuery
.fx
, "interval", jQuery
.fx
.interval
,
403 "jQuery.fx.interval is deprecated" );
406 var oldLoad
= jQuery
.fn
.load
,
407 oldEventAdd
= jQuery
.event
.add
,
408 originalFix
= jQuery
.event
.fix
;
410 jQuery
.event
.props
= [];
411 jQuery
.event
.fixHooks
= {};
413 migrateWarnProp( jQuery
.event
.props
, "concat", jQuery
.event
.props
.concat
,
414 "jQuery.event.props.concat() is deprecated and removed" );
416 jQuery
.event
.fix = function( originalEvent
) {
418 type
= originalEvent
.type
,
419 fixHook
= this.fixHooks
[ type
],
420 props
= jQuery
.event
.props
;
422 if ( props
.length
) {
423 migrateWarn( "jQuery.event.props are deprecated and removed: " + props
.join() );
424 while ( props
.length
) {
425 jQuery
.event
.addProp( props
.pop() );
429 if ( fixHook
&& !fixHook
._migrated_
) {
430 fixHook
._migrated_
= true;
431 migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type
);
432 if ( ( props
= fixHook
.props
) && props
.length
) {
433 while ( props
.length
) {
434 jQuery
.event
.addProp( props
.pop() );
439 event
= originalFix
.call( this, originalEvent
);
441 return fixHook
&& fixHook
.filter
? fixHook
.filter( event
, originalEvent
) : event
;
444 jQuery
.event
.add = function( elem
, types
) {
446 // This misses the multiple-types case but that seems awfully rare
447 if ( elem
=== window
&& types
=== "load" && window
.document
.readyState
=== "complete" ) {
448 migrateWarn( "jQuery(window).on('load'...) called after load event occurred" );
450 return oldEventAdd
.apply( this, arguments
);
453 jQuery
.each( [ "load", "unload", "error" ], function( _
, name
) {
455 jQuery
.fn
[ name
] = function() {
456 var args
= Array
.prototype.slice
.call( arguments
, 0 );
458 // If this is an ajax load() the first arg should be the string URL;
459 // technically this could also be the "Anything" arg of the event .load()
460 // which just goes to show why this dumb signature has been deprecated!
461 // jQuery custom builds that exclude the Ajax module justifiably die here.
462 if ( name
=== "load" && typeof args
[ 0 ] === "string" ) {
463 return oldLoad
.apply( this, args
);
466 migrateWarn( "jQuery.fn." + name
+ "() is deprecated" );
468 args
.splice( 0, 0, name
);
469 if ( arguments
.length
) {
470 return this.on
.apply( this, args
);
473 // Use .triggerHandler here because:
474 // - load and unload events don't need to bubble, only applied to window or image
475 // - error event should not bubble to window, although it does pre-1.7
476 // See http://bugs.jquery.com/ticket/11820
477 this.triggerHandler
.apply( this, args
);
483 // Trigger "ready" event only once, on document ready
485 jQuery( window
.document
).triggerHandler( "ready" );
488 jQuery
.event
.special
.ready
= {
490 if ( this === window
.document
) {
491 migrateWarn( "'ready' event is deprecated" );
498 bind: function( types
, data
, fn
) {
499 migrateWarn( "jQuery.fn.bind() is deprecated" );
500 return this.on( types
, null, data
, fn
);
502 unbind: function( types
, fn
) {
503 migrateWarn( "jQuery.fn.unbind() is deprecated" );
504 return this.off( types
, null, fn
);
506 delegate: function( selector
, types
, data
, fn
) {
507 migrateWarn( "jQuery.fn.delegate() is deprecated" );
508 return this.on( types
, selector
, data
, fn
);
510 undelegate: function( selector
, types
, fn
) {
511 migrateWarn( "jQuery.fn.undelegate() is deprecated" );
512 return arguments
.length
=== 1 ?
513 this.off( selector
, "**" ) :
514 this.off( types
, selector
|| "**", fn
);
516 hover: function( fnOver
, fnOut
) {
517 migrateWarn( "jQuery.fn.hover() is deprecated" );
518 return this.on( "mouseenter", fnOver
).on( "mouseleave", fnOut
|| fnOver
);
523 var oldOffset
= jQuery
.fn
.offset
;
525 jQuery
.fn
.offset = function() {
528 origin
= { top
: 0, left
: 0 };
530 if ( !elem
|| !elem
.nodeType
) {
531 migrateWarn( "jQuery.fn.offset() requires a valid DOM element" );
535 docElem
= ( elem
.ownerDocument
|| window
.document
).documentElement
;
536 if ( !jQuery
.contains( docElem
, elem
) ) {
537 migrateWarn( "jQuery.fn.offset() requires an element connected to a document" );
541 return oldOffset
.apply( this, arguments
);
545 var oldParam
= jQuery
.param
;
547 jQuery
.param = function( data
, traditional
) {
548 var ajaxTraditional
= jQuery
.ajaxSettings
&& jQuery
.ajaxSettings
.traditional
;
550 if ( traditional
=== undefined && ajaxTraditional
) {
552 migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" );
553 traditional
= ajaxTraditional
;
556 return oldParam
.call( this, data
, traditional
);
559 var oldSelf
= jQuery
.fn
.andSelf
|| jQuery
.fn
.addBack
;
561 jQuery
.fn
.andSelf = function() {
562 migrateWarn( "jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()" );
563 return oldSelf
.apply( this, arguments
);
567 var oldDeferred
= jQuery
.Deferred
,
570 // Action, add listener, callbacks, .then handlers, final state
571 [ "resolve", "done", jQuery
.Callbacks( "once memory" ),
572 jQuery
.Callbacks( "once memory" ), "resolved" ],
573 [ "reject", "fail", jQuery
.Callbacks( "once memory" ),
574 jQuery
.Callbacks( "once memory" ), "rejected" ],
575 [ "notify", "progress", jQuery
.Callbacks( "memory" ),
576 jQuery
.Callbacks( "memory" ) ]
579 jQuery
.Deferred = function( func
) {
580 var deferred
= oldDeferred(),
581 promise
= deferred
.promise();
583 deferred
.pipe
= promise
.pipe = function( /* fnDone, fnFail, fnProgress */ ) {
586 migrateWarn( "deferred.pipe() is deprecated" );
588 return jQuery
.Deferred( function( newDefer
) {
589 jQuery
.each( tuples
, function( i
, tuple
) {
590 var fn
= jQuery
.isFunction( fns
[ i
] ) && fns
[ i
];
592 // Deferred.done(function() { bind to newDefer or newDefer.resolve })
593 // deferred.fail(function() { bind to newDefer or newDefer.reject })
594 // deferred.progress(function() { bind to newDefer or newDefer.notify })
595 deferred
[ tuple
[ 1 ] ]( function() {
596 var returned
= fn
&& fn
.apply( this, arguments
);
597 if ( returned
&& jQuery
.isFunction( returned
.promise
) ) {
599 .done( newDefer
.resolve
)
600 .fail( newDefer
.reject
)
601 .progress( newDefer
.notify
);
603 newDefer
[ tuple
[ 0 ] + "With" ](
604 this === promise
? newDefer
.promise() : this,
605 fn
? [ returned
] : arguments
616 func
.call( deferred
, deferred
);
622 // Preserve handler of uncaught exceptions in promise chains
623 jQuery
.Deferred
.exceptionHook
= oldDeferred
.exceptionHook
;