weekly release 3.1dev
[moodle.git] / lib / jquery / jquery-migrate-1.2.1.js
CommitLineData
63c88397 1/*!\r
09bacfd7 2 * jQuery Migrate - v1.2.1 - 2013-05-08\r
63c88397
PS
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
10\r
11var warnedAbout = {};\r
12\r
13// List of warnings already given; public read only\r
14jQuery.migrateWarnings = [];\r
15\r
16// Set to true to prevent console output; migrateWarnings still maintained\r
17// jQuery.migrateMute = false;\r
18\r
19// Show a message on the console so devs know we're active\r
09bacfd7
PS
20if ( !jQuery.migrateMute && window.console && window.console.log ) {\r
21 window.console.log("JQMIGRATE: Logging is active");\r
63c88397
PS
22}\r
23\r
24// Set to false to disable traces that appear with warnings\r
25if ( jQuery.migrateTrace === undefined ) {\r
26 jQuery.migrateTrace = true;\r
27}\r
28\r
29// Forget any warnings we've already given; public\r
30jQuery.migrateReset = function() {\r
31 warnedAbout = {};\r
32 jQuery.migrateWarnings.length = 0;\r
33};\r
34\r
35function migrateWarn( msg) {\r
09bacfd7 36 var console = window.console;\r
63c88397
PS
37 if ( !warnedAbout[ msg ] ) {\r
38 warnedAbout[ msg ] = true;\r
39 jQuery.migrateWarnings.push( msg );\r
09bacfd7 40 if ( console && console.warn && !jQuery.migrateMute ) {\r
63c88397
PS
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
48\r
49function 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
71\r
72 // Non-ES5 (or broken) browser; just set the property\r
73 jQuery._definePropertyBroken = true;\r
74 obj[ prop ] = value;\r
75}\r
76\r
77if ( 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
81\r
82\r
83var 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
93\r
94// jQuery.attrFn\r
95migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );\r
96\r
97jQuery.attr = function( elem, name, value, pass ) {\r
98 var lowerName = name.toLowerCase(),\r
99 nType = elem && elem.nodeType;\r
100\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
112\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
118\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
129\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
146\r
147 elem.setAttribute( name, name.toLowerCase() );\r
148 }\r
149 return name;\r
150 }\r
151 };\r
152\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
158\r
159 return oldAttr.call( jQuery, elem, name, value );\r
160};\r
161\r
162// attrHooks: value\r
163jQuery.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
188\r
189\r
190var matched, browser,\r
191 oldInit = jQuery.fn.init,\r
192 oldParseJSON = jQuery.parseJSON,\r
09bacfd7
PS
193 // Note: XSS check is done below after string is trimmed\r
194 rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;\r
63c88397
PS
195\r
196// $(html) "looks like html" rule change\r
197jQuery.fn.init = function( selector, context, rootjQuery ) {\r
198 var match;\r
199\r
200 if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&\r
09bacfd7 201 (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {\r
63c88397
PS
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
09bacfd7
PS
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
63c88397
PS
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
09bacfd7 221 return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),\r
63c88397
PS
222 context, rootjQuery );\r
223 }\r
224 }\r
225 return oldInit.apply( this, arguments );\r
226};\r
227jQuery.fn.init.prototype = jQuery.fn;\r
228\r
229// Let $.parseJSON(falsy_value) return null\r
230jQuery.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
237\r
238jQuery.uaMatch = function( ua ) {\r
239 ua = ua.toLowerCase();\r
240\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
247\r
248 return {\r
249 browser: match[ 1 ] || "",\r
250 version: match[ 2 ] || "0"\r
251 };\r
252};\r
253\r
254// Don't clobber any existing jQuery.browser in case it's different\r
255if ( !jQuery.browser ) {\r
256 matched = jQuery.uaMatch( navigator.userAgent );\r
257 browser = {};\r
258\r
259 if ( matched.browser ) {\r
260 browser[ matched.browser ] = true;\r
261 browser.version = matched.version;\r
262 }\r
263\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
270\r
271 jQuery.browser = browser;\r
272}\r
273\r
274// Warn if the code tries to get jQuery.browser\r
275migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );\r
276\r
277jQuery.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
290\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
298\r
299\r
300// Ensure that $.ajax gets the new parseJSON defined in core.js\r
301jQuery.ajaxSetup({\r
302 converters: {\r
303 "text json": jQuery.parseJSON\r
304 }\r
305});\r
306\r
307\r
308var oldFnData = jQuery.fn.data;\r
309\r
310jQuery.fn.data = function( name ) {\r
311 var ret, evt,\r
312 elem = this[0];\r
313\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
325\r
326\r
327var rscriptType = /\/(java|ecma)script/i,\r
328 oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;\r
329\r
330jQuery.fn.andSelf = function() {\r
331 migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");\r
332 return oldSelf.apply( this, arguments );\r
333};\r
334\r
335// Since jQuery.clean is used internally on older versions, we only shim if it's missing\r
336if ( !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
342\r
343 migrateWarn("jQuery.clean() is deprecated");\r
344\r
345 var i, elem, handleScript, jsTags,\r
346 ret = [];\r
347\r
348 jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );\r
349\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
363\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
372\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
380\r
381 return ret;\r
382 };\r
383}\r
384\r
385var 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
403\r
404// Event props removed in 1.9, put them back if needed; no practical way to warn them\r
405if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {\r
406 jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );\r
407}\r
408\r
409// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7\r
410if ( jQuery.event.dispatch ) {\r
411 migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );\r
412}\r
413\r
414// Support for 'hover' pseudo-event and ajax event warnings\r
415jQuery.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
421jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){\r
422 eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );\r
423};\r
424\r
425jQuery.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
436\r
437jQuery.fn.toggle = function( fn, fn2 ) {\r
438\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
444\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
453\r
454 // Make sure that clicks stop\r
455 event.preventDefault();\r
456\r
457 // and execute the function\r
458 return args[ lastToggle ].apply( this, arguments ) || false;\r
459 };\r
460\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
466\r
467 return this.click( toggler );\r
468};\r
469\r
470jQuery.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
478\r
479jQuery.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
487\r
488// Turn global events into document-triggered events\r
489jQuery.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
495jQuery.each( ajaxEvents.split("|"),\r
496 function( _, name ) {\r
497 jQuery.event.special[ name ] = {\r
498 setup: function() {\r
499 var elem = this;\r
500\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
519\r
520\r
521})( jQuery, window );\r