Merge branch 'MDL-51924-master' of git://github.com/barbararamiro/moodle
[moodle.git] / lib / jquery / jquery-migrate-1.2.1.js
blobdbe8cbd4d8ce798d54fcd40243ae1739b9069bdd
1 /*!\r
2  * jQuery Migrate - v1.2.1 - 2013-05-08\r
3  * https://github.com/jquery/jquery-migrate\r
4  * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT\r
5  */\r
6 (function( jQuery, window, undefined ) {\r
7 // See http://bugs.jquery.com/ticket/13335\r
8 // "use strict";\r
9 \r
11 var warnedAbout = {};\r
13 // List of warnings already given; public read only\r
14 jQuery.migrateWarnings = [];\r
16 // Set to true to prevent console output; migrateWarnings still maintained\r
17 // jQuery.migrateMute = false;\r
19 // Show a message on the console so devs know we're active\r
20 if ( !jQuery.migrateMute && window.console && window.console.log ) {\r
21         window.console.log("JQMIGRATE: Logging is active");\r
22 }\r
24 // Set to false to disable traces that appear with warnings\r
25 if ( jQuery.migrateTrace === undefined ) {\r
26         jQuery.migrateTrace = true;\r
27 }\r
29 // Forget any warnings we've already given; public\r
30 jQuery.migrateReset = function() {\r
31         warnedAbout = {};\r
32         jQuery.migrateWarnings.length = 0;\r
33 };\r
35 function migrateWarn( msg) {\r
36         var console = window.console;\r
37         if ( !warnedAbout[ msg ] ) {\r
38                 warnedAbout[ msg ] = true;\r
39                 jQuery.migrateWarnings.push( msg );\r
40                 if ( console && console.warn && !jQuery.migrateMute ) {\r
41                         console.warn( "JQMIGRATE: " + msg );\r
42                         if ( jQuery.migrateTrace && console.trace ) {\r
43                                 console.trace();\r
44                         }\r
45                 }\r
46         }\r
47 }\r
49 function migrateWarnProp( obj, prop, value, msg ) {\r
50         if ( Object.defineProperty ) {\r
51                 // On ES5 browsers (non-oldIE), warn if the code tries to get prop;\r
52                 // allow property to be overwritten in case some other plugin wants it\r
53                 try {\r
54                         Object.defineProperty( obj, prop, {\r
55                                 configurable: true,\r
56                                 enumerable: true,\r
57                                 get: function() {\r
58                                         migrateWarn( msg );\r
59                                         return value;\r
60                                 },\r
61                                 set: function( newValue ) {\r
62                                         migrateWarn( msg );\r
63                                         value = newValue;\r
64                                 }\r
65                         });\r
66                         return;\r
67                 } catch( err ) {\r
68                         // IE8 is a dope about Object.defineProperty, can't warn there\r
69                 }\r
70         }\r
72         // Non-ES5 (or broken) browser; just set the property\r
73         jQuery._definePropertyBroken = true;\r
74         obj[ prop ] = value;\r
75 }\r
77 if ( document.compatMode === "BackCompat" ) {\r
78         // jQuery has never supported or tested Quirks Mode\r
79         migrateWarn( "jQuery is not compatible with Quirks Mode" );\r
80 }\r
83 var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,\r
84         oldAttr = jQuery.attr,\r
85         valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||\r
86                 function() { return null; },\r
87         valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||\r
88                 function() { return undefined; },\r
89         rnoType = /^(?:input|button)$/i,\r
90         rnoAttrNodeType = /^[238]$/,\r
91         rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\r
92         ruseDefault = /^(?:checked|selected)$/i;\r
94 // jQuery.attrFn\r
95 migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );\r
97 jQuery.attr = function( elem, name, value, pass ) {\r
98         var lowerName = name.toLowerCase(),\r
99                 nType = elem && elem.nodeType;\r
101         if ( pass ) {\r
102                 // Since pass is used internally, we only warn for new jQuery\r
103                 // versions where there isn't a pass arg in the formal params\r
104                 if ( oldAttr.length < 4 ) {\r
105                         migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");\r
106                 }\r
107                 if ( elem && !rnoAttrNodeType.test( nType ) &&\r
108                         (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {\r
109                         return jQuery( elem )[ name ]( value );\r
110                 }\r
111         }\r
113         // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking\r
114         // for disconnected elements we don't warn on $( "<button>", { type: "button" } ).\r
115         if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {\r
116                 migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");\r
117         }\r
119         // Restore boolHook for boolean property/attribute synchronization\r
120         if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {\r
121                 jQuery.attrHooks[ lowerName ] = {\r
122                         get: function( elem, name ) {\r
123                                 // Align boolean attributes with corresponding properties\r
124                                 // Fall back to attribute presence where some booleans are not supported\r
125                                 var attrNode,\r
126                                         property = jQuery.prop( elem, name );\r
127                                 return property === true || typeof property !== "boolean" &&\r
128                                         ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?\r
130                                         name.toLowerCase() :\r
131                                         undefined;\r
132                         },\r
133                         set: function( elem, value, name ) {\r
134                                 var propName;\r
135                                 if ( value === false ) {\r
136                                         // Remove boolean attributes when set to false\r
137                                         jQuery.removeAttr( elem, name );\r
138                                 } else {\r
139                                         // value is true since we know at this point it's type boolean and not false\r
140                                         // Set boolean attributes to the same name and set the DOM property\r
141                                         propName = jQuery.propFix[ name ] || name;\r
142                                         if ( propName in elem ) {\r
143                                                 // Only set the IDL specifically if it already exists on the element\r
144                                                 elem[ propName ] = true;\r
145                                         }\r
147                                         elem.setAttribute( name, name.toLowerCase() );\r
148                                 }\r
149                                 return name;\r
150                         }\r
151                 };\r
153                 // Warn only for attributes that can remain distinct from their properties post-1.9\r
154                 if ( ruseDefault.test( lowerName ) ) {\r
155                         migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );\r
156                 }\r
157         }\r
159         return oldAttr.call( jQuery, elem, name, value );\r
160 };\r
162 // attrHooks: value\r
163 jQuery.attrHooks.value = {\r
164         get: function( elem, name ) {\r
165                 var nodeName = ( elem.nodeName || "" ).toLowerCase();\r
166                 if ( nodeName === "button" ) {\r
167                         return valueAttrGet.apply( this, arguments );\r
168                 }\r
169                 if ( nodeName !== "input" && nodeName !== "option" ) {\r
170                         migrateWarn("jQuery.fn.attr('value') no longer gets properties");\r
171                 }\r
172                 return name in elem ?\r
173                         elem.value :\r
174                         null;\r
175         },\r
176         set: function( elem, value ) {\r
177                 var nodeName = ( elem.nodeName || "" ).toLowerCase();\r
178                 if ( nodeName === "button" ) {\r
179                         return valueAttrSet.apply( this, arguments );\r
180                 }\r
181                 if ( nodeName !== "input" && nodeName !== "option" ) {\r
182                         migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");\r
183                 }\r
184                 // Does not return so that setAttribute is also used\r
185                 elem.value = value;\r
186         }\r
187 };\r
190 var matched, browser,\r
191         oldInit = jQuery.fn.init,\r
192         oldParseJSON = jQuery.parseJSON,\r
193         // Note: XSS check is done below after string is trimmed\r
194         rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;\r
196 // $(html) "looks like html" rule change\r
197 jQuery.fn.init = function( selector, context, rootjQuery ) {\r
198         var match;\r
200         if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&\r
201                         (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {\r
202                 // This is an HTML string according to the "old" rules; is it still?\r
203                 if ( selector.charAt( 0 ) !== "<" ) {\r
204                         migrateWarn("$(html) HTML strings must start with '<' character");\r
205                 }\r
206                 if ( match[ 3 ] ) {\r
207                         migrateWarn("$(html) HTML text after last tag is ignored");\r
208                 }\r
209                 // Consistently reject any HTML-like string starting with a hash (#9521)\r
210                 // Note that this may break jQuery 1.6.x code that otherwise would work.\r
211                 if ( match[ 0 ].charAt( 0 ) === "#" ) {\r
212                         migrateWarn("HTML string cannot start with a '#' character");\r
213                         jQuery.error("JQMIGRATE: Invalid selector string (XSS)");\r
214                 }\r
215                 // Now process using loose rules; let pre-1.8 play too\r
216                 if ( context && context.context ) {\r
217                         // jQuery object as context; parseHTML expects a DOM object\r
218                         context = context.context;\r
219                 }\r
220                 if ( jQuery.parseHTML ) {\r
221                         return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),\r
222                                         context, rootjQuery );\r
223                 }\r
224         }\r
225         return oldInit.apply( this, arguments );\r
226 };\r
227 jQuery.fn.init.prototype = jQuery.fn;\r
229 // Let $.parseJSON(falsy_value) return null\r
230 jQuery.parseJSON = function( json ) {\r
231         if ( !json && json !== null ) {\r
232                 migrateWarn("jQuery.parseJSON requires a valid JSON string");\r
233                 return null;\r
234         }\r
235         return oldParseJSON.apply( this, arguments );\r
236 };\r
238 jQuery.uaMatch = function( ua ) {\r
239         ua = ua.toLowerCase();\r
241         var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||\r
242                 /(webkit)[ \/]([\w.]+)/.exec( ua ) ||\r
243                 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||\r
244                 /(msie) ([\w.]+)/.exec( ua ) ||\r
245                 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||\r
246                 [];\r
248         return {\r
249                 browser: match[ 1 ] || "",\r
250                 version: match[ 2 ] || "0"\r
251         };\r
252 };\r
254 // Don't clobber any existing jQuery.browser in case it's different\r
255 if ( !jQuery.browser ) {\r
256         matched = jQuery.uaMatch( navigator.userAgent );\r
257         browser = {};\r
259         if ( matched.browser ) {\r
260                 browser[ matched.browser ] = true;\r
261                 browser.version = matched.version;\r
262         }\r
264         // Chrome is Webkit, but Webkit is also Safari.\r
265         if ( browser.chrome ) {\r
266                 browser.webkit = true;\r
267         } else if ( browser.webkit ) {\r
268                 browser.safari = true;\r
269         }\r
271         jQuery.browser = browser;\r
274 // Warn if the code tries to get jQuery.browser\r
275 migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );\r
277 jQuery.sub = function() {\r
278         function jQuerySub( selector, context ) {\r
279                 return new jQuerySub.fn.init( selector, context );\r
280         }\r
281         jQuery.extend( true, jQuerySub, this );\r
282         jQuerySub.superclass = this;\r
283         jQuerySub.fn = jQuerySub.prototype = this();\r
284         jQuerySub.fn.constructor = jQuerySub;\r
285         jQuerySub.sub = this.sub;\r
286         jQuerySub.fn.init = function init( selector, context ) {\r
287                 if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\r
288                         context = jQuerySub( context );\r
289                 }\r
291                 return jQuery.fn.init.call( this, selector, context, rootjQuerySub );\r
292         };\r
293         jQuerySub.fn.init.prototype = jQuerySub.fn;\r
294         var rootjQuerySub = jQuerySub(document);\r
295         migrateWarn( "jQuery.sub() is deprecated" );\r
296         return jQuerySub;\r
297 };\r
300 // Ensure that $.ajax gets the new parseJSON defined in core.js\r
301 jQuery.ajaxSetup({\r
302         converters: {\r
303                 "text json": jQuery.parseJSON\r
304         }\r
305 });\r
308 var oldFnData = jQuery.fn.data;\r
310 jQuery.fn.data = function( name ) {\r
311         var ret, evt,\r
312                 elem = this[0];\r
314         // Handles 1.7 which has this behavior and 1.8 which doesn't\r
315         if ( elem && name === "events" && arguments.length === 1 ) {\r
316                 ret = jQuery.data( elem, name );\r
317                 evt = jQuery._data( elem, name );\r
318                 if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {\r
319                         migrateWarn("Use of jQuery.fn.data('events') is deprecated");\r
320                         return evt;\r
321                 }\r
322         }\r
323         return oldFnData.apply( this, arguments );\r
324 };\r
327 var rscriptType = /\/(java|ecma)script/i,\r
328         oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;\r
330 jQuery.fn.andSelf = function() {\r
331         migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");\r
332         return oldSelf.apply( this, arguments );\r
333 };\r
335 // Since jQuery.clean is used internally on older versions, we only shim if it's missing\r
336 if ( !jQuery.clean ) {\r
337         jQuery.clean = function( elems, context, fragment, scripts ) {\r
338                 // Set context per 1.8 logic\r
339                 context = context || document;\r
340                 context = !context.nodeType && context[0] || context;\r
341                 context = context.ownerDocument || context;\r
343                 migrateWarn("jQuery.clean() is deprecated");\r
345                 var i, elem, handleScript, jsTags,\r
346                         ret = [];\r
348                 jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );\r
350                 // Complex logic lifted directly from jQuery 1.8\r
351                 if ( fragment ) {\r
352                         // Special handling of each script element\r
353                         handleScript = function( elem ) {\r
354                                 // Check if we consider it executable\r
355                                 if ( !elem.type || rscriptType.test( elem.type ) ) {\r
356                                         // Detach the script and store it in the scripts array (if provided) or the fragment\r
357                                         // Return truthy to indicate that it has been handled\r
358                                         return scripts ?\r
359                                                 scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :\r
360                                                 fragment.appendChild( elem );\r
361                                 }\r
362                         };\r
364                         for ( i = 0; (elem = ret[i]) != null; i++ ) {\r
365                                 // Check if we're done after handling an executable script\r
366                                 if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {\r
367                                         // Append to fragment and handle embedded scripts\r
368                                         fragment.appendChild( elem );\r
369                                         if ( typeof elem.getElementsByTagName !== "undefined" ) {\r
370                                                 // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration\r
371                                                 jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );\r
373                                                 // Splice the scripts into ret after their former ancestor and advance our index beyond them\r
374                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\r
375                                                 i += jsTags.length;\r
376                                         }\r
377                                 }\r
378                         }\r
379                 }\r
381                 return ret;\r
382         };\r
385 var eventAdd = jQuery.event.add,\r
386         eventRemove = jQuery.event.remove,\r
387         eventTrigger = jQuery.event.trigger,\r
388         oldToggle = jQuery.fn.toggle,\r
389         oldLive = jQuery.fn.live,\r
390         oldDie = jQuery.fn.die,\r
391         ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",\r
392         rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),\r
393         rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,\r
394         hoverHack = function( events ) {\r
395                 if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {\r
396                         return events;\r
397                 }\r
398                 if ( rhoverHack.test( events ) ) {\r
399                         migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");\r
400                 }\r
401                 return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );\r
402         };\r
404 // Event props removed in 1.9, put them back if needed; no practical way to warn them\r
405 if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {\r
406         jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );\r
409 // Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7\r
410 if ( jQuery.event.dispatch ) {\r
411         migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );\r
414 // Support for 'hover' pseudo-event and ajax event warnings\r
415 jQuery.event.add = function( elem, types, handler, data, selector ){\r
416         if ( elem !== document && rajaxEvent.test( types ) ) {\r
417                 migrateWarn( "AJAX events should be attached to document: " + types );\r
418         }\r
419         eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );\r
420 };\r
421 jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){\r
422         eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );\r
423 };\r
425 jQuery.fn.error = function() {\r
426         var args = Array.prototype.slice.call( arguments, 0);\r
427         migrateWarn("jQuery.fn.error() is deprecated");\r
428         args.splice( 0, 0, "error" );\r
429         if ( arguments.length ) {\r
430                 return this.bind.apply( this, args );\r
431         }\r
432         // error event should not bubble to window, although it does pre-1.7\r
433         this.triggerHandler.apply( this, args );\r
434         return this;\r
435 };\r
437 jQuery.fn.toggle = function( fn, fn2 ) {\r
439         // Don't mess with animation or css toggles\r
440         if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {\r
441                 return oldToggle.apply( this, arguments );\r
442         }\r
443         migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");\r
445         // Save reference to arguments for access in closure\r
446         var args = arguments,\r
447                 guid = fn.guid || jQuery.guid++,\r
448                 i = 0,\r
449                 toggler = function( event ) {\r
450                         // Figure out which function to execute\r
451                         var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;\r
452                         jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );\r
454                         // Make sure that clicks stop\r
455                         event.preventDefault();\r
457                         // and execute the function\r
458                         return args[ lastToggle ].apply( this, arguments ) || false;\r
459                 };\r
461         // link all the functions, so any of them can unbind this click handler\r
462         toggler.guid = guid;\r
463         while ( i < args.length ) {\r
464                 args[ i++ ].guid = guid;\r
465         }\r
467         return this.click( toggler );\r
468 };\r
470 jQuery.fn.live = function( types, data, fn ) {\r
471         migrateWarn("jQuery.fn.live() is deprecated");\r
472         if ( oldLive ) {\r
473                 return oldLive.apply( this, arguments );\r
474         }\r
475         jQuery( this.context ).on( types, this.selector, data, fn );\r
476         return this;\r
477 };\r
479 jQuery.fn.die = function( types, fn ) {\r
480         migrateWarn("jQuery.fn.die() is deprecated");\r
481         if ( oldDie ) {\r
482                 return oldDie.apply( this, arguments );\r
483         }\r
484         jQuery( this.context ).off( types, this.selector || "**", fn );\r
485         return this;\r
486 };\r
488 // Turn global events into document-triggered events\r
489 jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){\r
490         if ( !elem && !rajaxEvent.test( event ) ) {\r
491                 migrateWarn( "Global events are undocumented and deprecated" );\r
492         }\r
493         return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );\r
494 };\r
495 jQuery.each( ajaxEvents.split("|"),\r
496         function( _, name ) {\r
497                 jQuery.event.special[ name ] = {\r
498                         setup: function() {\r
499                                 var elem = this;\r
501                                 // The document needs no shimming; must be !== for oldIE\r
502                                 if ( elem !== document ) {\r
503                                         jQuery.event.add( document, name + "." + jQuery.guid, function() {\r
504                                                 jQuery.event.trigger( name, null, elem, true );\r
505                                         });\r
506                                         jQuery._data( this, name, jQuery.guid++ );\r
507                                 }\r
508                                 return false;\r
509                         },\r
510                         teardown: function() {\r
511                                 if ( this !== document ) {\r
512                                         jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );\r
513                                 }\r
514                                 return false;\r
515                         }\r
516                 };\r
517         }\r
518 );\r
521 })( jQuery, window );\r