diff options
-rw-r--r-- | Gruntfile.js | 8 | ||||
-rw-r--r-- | bower.json | 4 | ||||
-rw-r--r-- | external/jquery-migrate-1.4.1/LICENSE.txt | 36 | ||||
-rw-r--r-- | external/jquery-migrate-1.4.1/jquery-migrate.js | 752 | ||||
-rw-r--r-- | external/jquery-migrate-3.0.0/LICENSE.txt | 36 | ||||
-rw-r--r-- | external/jquery-migrate-3.0.0/jquery-migrate.js | 540 | ||||
-rw-r--r-- | tests/lib/bootstrap.js | 40 | ||||
-rw-r--r-- | tests/lib/qunit.js | 5 |
8 files changed, 1415 insertions, 6 deletions
diff --git a/Gruntfile.js b/Gruntfile.js index 66a75d66e..1aac2c454 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -395,7 +395,13 @@ grunt.initConfig({ "jquery-3.1.0/LICENSE.txt": "jquery-3.1.0/LICENSE.txt", "jquery-3.1.1/jquery.js": "jquery-3.1.1/dist/jquery.js", - "jquery-3.1.1/LICENSE.txt": "jquery-3.1.1/LICENSE.txt" + "jquery-3.1.1/LICENSE.txt": "jquery-3.1.1/LICENSE.txt", + + "jquery-migrate-1.4.1/jquery-migrate.js": "jquery-migrate-1.4.1/dist/jquery-migrate.js", + "jquery-migrate-1.4.1/LICENSE.txt": "jquery-migrate-1.4.1/LICENSE.txt", + + "jquery-migrate-3.0.0/jquery-migrate.js": "jquery-migrate-3.0.0/dist/jquery-migrate.js", + "jquery-migrate-3.0.0/LICENSE.txt": "jquery-migrate-3.0.0/LICENSE.txt" } } }, diff --git a/bower.json b/bower.json index e4df60cea..1af4b8ead 100644 --- a/bower.json +++ b/bower.json @@ -59,6 +59,8 @@ "jquery-2.2.4": "jquery#2.2.4", "jquery-3.0.0": "jquery#3.0.0", "jquery-3.1.0": "jquery#3.1.0", - "jquery-3.1.1": "jquery#3.1.1" + "jquery-3.1.1": "jquery#3.1.1", + "jquery-migrate-1.4.1": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-1.4.1.tgz", + "jquery-migrate-3.0.0": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-3.0.0.tgz" } } diff --git a/external/jquery-migrate-1.4.1/LICENSE.txt b/external/jquery-migrate-1.4.1/LICENSE.txt new file mode 100644 index 000000000..9dfa07145 --- /dev/null +++ b/external/jquery-migrate-1.4.1/LICENSE.txt @@ -0,0 +1,36 @@ +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-migrate + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/external/jquery-migrate-1.4.1/jquery-migrate.js b/external/jquery-migrate-1.4.1/jquery-migrate.js new file mode 100644 index 000000000..89437ebed --- /dev/null +++ b/external/jquery-migrate-1.4.1/jquery-migrate.js @@ -0,0 +1,752 @@ +/*! + * jQuery Migrate - v1.4.1 - 2016-05-19 + * Copyright jQuery Foundation and other contributors + */ +(function( jQuery, window, undefined ) { +// See http://bugs.jquery.com/ticket/13335 +// "use strict"; + + +jQuery.migrateVersion = "1.4.1"; + + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to true to prevent console output; migrateWarnings still maintained +// jQuery.migrateMute = false; + +// Show a message on the console so devs know we're active +if ( window.console && window.console.log ) { + window.console.log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); +} + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + if ( Object.defineProperty ) { + // On ES5 browsers (non-oldIE), warn if the code tries to get prop; + // allow property to be overwritten in case some other plugin wants it + try { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + }, + set: function( newValue ) { + migrateWarn( msg ); + value = newValue; + } + }); + return; + } catch( err ) { + // IE8 is a dope about Object.defineProperty, can't warn there + } + } + + // Non-ES5 (or broken) browser; just set the property + jQuery._definePropertyBroken = true; + obj[ prop ] = value; +} + +if ( document.compatMode === "BackCompat" ) { + // jQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn, + oldAttr = jQuery.attr, + valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get || + function() { return null; }, + valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set || + function() { return undefined; }, + rnoType = /^(?:input|button)$/i, + rnoAttrNodeType = /^[238]$/, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + ruseDefault = /^(?:checked|selected)$/i; + +// jQuery.attrFn +migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" ); + +jQuery.attr = function( elem, name, value, pass ) { + var lowerName = name.toLowerCase(), + nType = elem && elem.nodeType; + + if ( pass ) { + // Since pass is used internally, we only warn for new jQuery + // versions where there isn't a pass arg in the formal params + if ( oldAttr.length < 4 ) { + migrateWarn("jQuery.fn.attr( props, pass ) is deprecated"); + } + if ( elem && !rnoAttrNodeType.test( nType ) && + (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) { + return jQuery( elem )[ name ]( value ); + } + } + + // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking + // for disconnected elements we don't warn on $( "<button>", { type: "button" } ). + if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) { + migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8"); + } + + // Restore boolHook for boolean property/attribute synchronization + if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) { + jQuery.attrHooks[ lowerName ] = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && + ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } + }; + + // Warn only for attributes that can remain distinct from their properties post-1.9 + if ( ruseDefault.test( lowerName ) ) { + migrateWarn( "jQuery.fn.attr('" + lowerName + "') might use property instead of attribute" ); + } + } + + return oldAttr.call( jQuery, elem, name, value ); +}; + +// attrHooks: value +jQuery.attrHooks.value = { + get: function( elem, name ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "button" ) { + return valueAttrGet.apply( this, arguments ); + } + if ( nodeName !== "input" && nodeName !== "option" ) { + migrateWarn("jQuery.fn.attr('value') no longer gets properties"); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "button" ) { + return valueAttrSet.apply( this, arguments ); + } + if ( nodeName !== "input" && nodeName !== "option" ) { + migrateWarn("jQuery.fn.attr('value', val) no longer sets properties"); + } + // Does not return so that setAttribute is also used + elem.value = value; + } +}; + + +var matched, browser, + oldInit = jQuery.fn.init, + oldFind = jQuery.find, + oldParseJSON = jQuery.parseJSON, + rspaceAngle = /^\s*</, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g, + // Note: XSS check is done below after string is trimmed + rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/; + +// $(html) "looks like html" rule change +jQuery.fn.init = function( selector, context, rootjQuery ) { + var match, ret; + + if ( selector && typeof selector === "string" ) { + if ( !jQuery.isPlainObject( context ) && + (match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) { + + // This is an HTML string according to the "old" rules; is it still? + if ( !rspaceAngle.test( selector ) ) { + migrateWarn("$(html) HTML strings must start with '<' character"); + } + if ( match[ 3 ] ) { + migrateWarn("$(html) HTML text after last tag is ignored"); + } + + // Consistently reject any HTML-like string starting with a hash (gh-9521) + // Note that this may break jQuery 1.6.x code that otherwise would work. + if ( match[ 0 ].charAt( 0 ) === "#" ) { + migrateWarn("HTML string cannot start with a '#' character"); + jQuery.error("JQMIGRATE: Invalid selector string (XSS)"); + } + + // Now process using loose rules; let pre-1.8 play too + // Is this a jQuery context? parseHTML expects a DOM element (#178) + if ( context && context.context && context.context.nodeType ) { + context = context.context; + } + + if ( jQuery.parseHTML ) { + return oldInit.call( this, + jQuery.parseHTML( match[ 2 ], context && context.ownerDocument || + context || document, true ), context, rootjQuery ); + } + } + } + + ret = oldInit.apply( this, arguments ); + + // Fill in selector and context properties so .live() works + if ( selector && selector.selector !== undefined ) { + // A jQuery object, copy its properties + ret.selector = selector.selector; + ret.context = selector.context; + + } else { + ret.selector = typeof selector === "string" ? selector : ""; + if ( selector ) { + ret.context = selector.nodeType? selector : context || document; + } + } + + return ret; +}; +jQuery.fn.init.prototype = jQuery.fn; + +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 { + 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 { + document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +for ( findProp in oldFind ) { + if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) { + jQuery.find[ findProp ] = oldFind[ findProp ]; + } +} + +// Let $.parseJSON(falsy_value) return null +jQuery.parseJSON = function( json ) { + if ( !json ) { + migrateWarn("jQuery.parseJSON requires a valid JSON string"); + return null; + } + return oldParseJSON.apply( this, arguments ); +}; + +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +// Don't clobber any existing jQuery.browser in case it's different +if ( !jQuery.browser ) { + matched = jQuery.uaMatch( navigator.userAgent ); + browser = {}; + + if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; + } + + // Chrome is Webkit, but Webkit is also Safari. + if ( browser.chrome ) { + browser.webkit = true; + } else if ( browser.webkit ) { + browser.safari = true; + } + + jQuery.browser = browser; +} + +// Warn if the code tries to get jQuery.browser +migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" ); + +// jQuery.boxModel deprecated in 1.3, jQuery.support.boxModel deprecated in 1.7 +jQuery.boxModel = jQuery.support.boxModel = (document.compatMode === "CSS1Compat"); +migrateWarnProp( jQuery, "boxModel", jQuery.boxModel, "jQuery.boxModel is deprecated" ); +migrateWarnProp( jQuery.support, "boxModel", jQuery.support.boxModel, "jQuery.support.boxModel is deprecated" ); + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + var instance = jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + return instance instanceof jQuerySub ? + instance : + jQuerySub( instance ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + migrateWarn( "jQuery.sub() is deprecated" ); + return jQuerySub; +}; + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); + return this.length; +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + }); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +// Ensure that $.ajax gets the new parseJSON defined in core.js +jQuery.ajaxSetup({ + converters: { + "text json": jQuery.parseJSON + } +}); + + +var oldFnData = jQuery.fn.data; + +jQuery.fn.data = function( name ) { + var ret, evt, + elem = this[0]; + + // Handles 1.7 which has this behavior and 1.8 which doesn't + if ( elem && name === "events" && arguments.length === 1 ) { + ret = jQuery.data( elem, name ); + evt = jQuery._data( elem, name ); + if ( ( ret === undefined || ret === evt ) && evt !== undefined ) { + migrateWarn("Use of jQuery.fn.data('events') is deprecated"); + return evt; + } + } + return oldFnData.apply( this, arguments ); +}; + + +var rscriptType = /\/(java|ecma)script/i; + +// Since jQuery.clean is used internally on older versions, we only shim if it's missing +if ( !jQuery.clean ) { + jQuery.clean = function( elems, context, fragment, scripts ) { + // Set context per 1.8 logic + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + migrateWarn("jQuery.clean() is deprecated"); + + var i, elem, handleScript, jsTags, + ret = []; + + jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes ); + + // Complex logic lifted directly from jQuery 1.8 + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }; +} + +var eventAdd = jQuery.event.add, + eventRemove = jQuery.event.remove, + eventTrigger = jQuery.event.trigger, + oldToggle = jQuery.fn.toggle, + oldLive = jQuery.fn.live, + oldDie = jQuery.fn.die, + oldLoad = jQuery.fn.load, + ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess", + rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ), + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + hoverHack = function( events ) { + if ( typeof( events ) !== "string" || jQuery.event.special.hover ) { + return events; + } + if ( rhoverHack.test( events ) ) { + migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'"); + } + return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +// Event props removed in 1.9, put them back if needed; no practical way to warn them +if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) { + jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" ); +} + +// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7 +if ( jQuery.event.dispatch ) { + migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" ); +} + +// Support for 'hover' pseudo-event and ajax event warnings +jQuery.event.add = function( elem, types, handler, data, selector ){ + if ( elem !== document && rajaxEvent.test( types ) ) { + migrateWarn( "AJAX events should be attached to document: " + types ); + } + eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector ); +}; +jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){ + eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes ); +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.bind.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +}); + +jQuery.fn.toggle = function( fn, fn2 ) { + + // Don't mess with animation or css toggles + if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) { + return oldToggle.apply( this, arguments ); + } + migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated"); + + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); +}; + +jQuery.fn.live = function( types, data, fn ) { + migrateWarn("jQuery.fn.live() is deprecated"); + if ( oldLive ) { + return oldLive.apply( this, arguments ); + } + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; +}; + +jQuery.fn.die = function( types, fn ) { + migrateWarn("jQuery.fn.die() is deprecated"); + if ( oldDie ) { + return oldDie.apply( this, arguments ); + } + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; +}; + +// Turn global events into document-triggered events +jQuery.event.trigger = function( event, data, elem, onlyHandlers ){ + if ( !elem && !rajaxEvent.test( event ) ) { + migrateWarn( "Global events are undocumented and deprecated" ); + } + return eventTrigger.call( this, event, data, elem || document, onlyHandlers ); +}; +jQuery.each( ajaxEvents.split("|"), + function( _, name ) { + jQuery.event.special[ name ] = { + setup: function() { + var elem = this; + + // The document needs no shimming; must be !== for oldIE + if ( elem !== document ) { + jQuery.event.add( document, name + "." + jQuery.guid, function() { + jQuery.event.trigger( name, Array.prototype.slice.call( arguments, 1 ), elem, true ); + }); + jQuery._data( this, name, jQuery.guid++ ); + } + return false; + }, + teardown: function() { + if ( this !== document ) { + jQuery.event.remove( document, name + "." + jQuery._data( this, name ) ); + } + return false; + } + }; + } +); + +jQuery.event.special.ready = { + setup: function() { + if ( this === document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack, + oldFnFind = jQuery.fn.find; + +jQuery.fn.andSelf = function() { + migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()"); + return oldSelf.apply( this, arguments ); +}; + +jQuery.fn.find = function( selector ) { + var ret = oldFnFind.apply( this, arguments ); + ret.context = this.context; + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; +}; + + +// jQuery 1.6 did not support Callbacks, do not warn there +if ( jQuery.Callbacks ) { + + var oldDeferred = jQuery.Deferred, + tuples = [ + // action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), + jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), + jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory"), + jQuery.Callbacks("memory") ] + ]; + + jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + }); + }); + fns = null; + }).promise(); + + }; + + deferred.isResolved = function() { + migrateWarn( "deferred.isResolved is deprecated" ); + return deferred.state() === "resolved"; + }; + + deferred.isRejected = function() { + migrateWarn( "deferred.isRejected is deprecated" ); + return deferred.state() === "rejected"; + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; + }; + +} + +})( jQuery, window ); diff --git a/external/jquery-migrate-3.0.0/LICENSE.txt b/external/jquery-migrate-3.0.0/LICENSE.txt new file mode 100644 index 000000000..9dfa07145 --- /dev/null +++ b/external/jquery-migrate-3.0.0/LICENSE.txt @@ -0,0 +1,36 @@ +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-migrate + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/external/jquery-migrate-3.0.0/jquery-migrate.js b/external/jquery-migrate-3.0.0/jquery-migrate.js new file mode 100644 index 000000000..05b1a803c --- /dev/null +++ b/external/jquery-migrate-3.0.0/jquery-migrate.js @@ -0,0 +1,540 @@ +/*! + * jQuery Migrate - v3.0.0 - 2016-06-09 + * Copyright jQuery Foundation and other contributors + */ +(function( jQuery, window ) { +"use strict"; + + +jQuery.migrateVersion = "3.0.0"; + + +( function() { + + // Support: IE9 only + // IE9 only creates console object when dev tools are first opened + // Also, avoid Function#bind here to simplify PhantomJS usage + var log = window.console && window.console.log && + function() { window.console.log.apply( window.console, arguments ); }, + rbadVersions = /^[12]\./; + + if ( !log ) { + return; + } + + // Need jQuery 3.0.0+ and no older Migrate loaded + if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) { + log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" ); + } + if ( jQuery.migrateWarnings ) { + log( "JQMIGRATE: Migrate plugin loaded multiple times" ); + } + + // Show a message on the console so devs know we're active + log( "JQMIGRATE: Migrate is installed" + + ( jQuery.migrateMute ? "" : " with logging active" ) + + ", version " + jQuery.migrateVersion ); + +} )(); + +var warnedAbout = {}; + +// List of warnings already given; public read only +jQuery.migrateWarnings = []; + +// Set to false to disable traces that appear with warnings +if ( jQuery.migrateTrace === undefined ) { + jQuery.migrateTrace = true; +} + +// Forget any warnings we've already given; public +jQuery.migrateReset = function() { + warnedAbout = {}; + jQuery.migrateWarnings.length = 0; +}; + +function migrateWarn( msg ) { + var console = window.console; + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); + if ( jQuery.migrateTrace && console.trace ) { + console.trace(); + } + } + } +} + +function migrateWarnProp( obj, prop, value, msg ) { + Object.defineProperty( obj, prop, { + configurable: true, + enumerable: true, + get: function() { + migrateWarn( msg ); + return value; + } + } ); +} + +if ( document.compatMode === "BackCompat" ) { + + // JQuery has never supported or tested Quirks Mode + migrateWarn( "jQuery is not compatible with Quirks Mode" ); +} + + +var oldInit = jQuery.fn.init, + oldIsNumeric = jQuery.isNumeric, + oldFind = jQuery.find, + rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, + rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g; + +jQuery.fn.init = function( arg1 ) { + var args = Array.prototype.slice.call( arguments ); + + if ( typeof arg1 === "string" && arg1 === "#" ) { + + // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0 + migrateWarn( "jQuery( '#' ) is not a valid selector" ); + args[ 0 ] = []; + } + + return oldInit.apply( this, args ); +}; +jQuery.fn.init.prototype = jQuery.fn; + +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 { + 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 { + document.querySelector( selector ); + migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] ); + args[ 0 ] = selector; + } catch ( err2 ) { + migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] ); + } + } + } + + return oldFind.apply( this, args ); +}; + +// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML) +var findProp; +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 +jQuery.fn.size = function() { + migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" ); + return this.length; +}; + +jQuery.parseJSON = function() { + migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" ); + return JSON.parse.apply( null, arguments ); +}; + +jQuery.isNumeric = function( val ) { + + // The jQuery 2.2.3 implementation of isNumeric + function isNumeric2( obj ) { + var realStringObj = obj && obj.toString(); + return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; + } + + var newValue = oldIsNumeric( val ), + oldValue = isNumeric2( val ); + + if ( newValue !== oldValue ) { + migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" ); + } + + return oldValue; +}; + +migrateWarnProp( jQuery, "unique", jQuery.uniqueSort, + "jQuery.unique is deprecated, use jQuery.uniqueSort" ); + +// Now jQuery.expr.pseudos is the standard incantation +migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos, + "jQuery.expr.filters is now jQuery.expr.pseudos" ); +migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos, + "jQuery.expr[\":\"] is now jQuery.expr.pseudos" ); + + +var oldAjax = jQuery.ajax; + +jQuery.ajax = function( ) { + var jQXHR = oldAjax.apply( this, arguments ); + + // Be sure we got a jQXHR (e.g., not sync) + if ( jQXHR.promise ) { + migrateWarnProp( jQXHR, "success", jQXHR.done, + "jQXHR.success is deprecated and removed" ); + migrateWarnProp( jQXHR, "error", jQXHR.fail, + "jQXHR.error is deprecated and removed" ); + migrateWarnProp( jQXHR, "complete", jQXHR.always, + "jQXHR.complete is deprecated and removed" ); + } + + return jQXHR; +}; + + +var oldRemoveAttr = jQuery.fn.removeAttr, + oldToggleClass = jQuery.fn.toggleClass, + rmatchNonSpace = /\S+/g; + +jQuery.fn.removeAttr = function( name ) { + var self = this; + + jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) { + if ( jQuery.expr.match.bool.test( attr ) ) { + migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr ); + self.prop( attr, false ); + } + } ); + + return oldRemoveAttr.apply( this, arguments ); +}; + +jQuery.fn.toggleClass = function( state ) { + + // Only deprecating no-args or single boolean arg + if ( state !== undefined && typeof state !== "boolean" ) { + return oldToggleClass.apply( this, arguments ); + } + + migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" ); + + // Toggle entire class name of each element + return this.each( function() { + var className = this.getAttribute && this.getAttribute( "class" ) || ""; + + if ( className ) { + jQuery.data( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || state === false ? + "" : + jQuery.data( this, "__className__" ) || "" + ); + } + } ); +}; + + +var internalSwapCall = false; + +// If this version of jQuery has .swap(), don't false-alarm on internal uses +if ( jQuery.swap ) { + jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) { + var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get; + + if ( oldHook ) { + jQuery.cssHooks[ name ].get = function() { + var ret; + + internalSwapCall = true; + ret = oldHook.apply( this, arguments ); + internalSwapCall = false; + return ret; + }; + } + } ); +} + +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + if ( !internalSwapCall ) { + migrateWarn( "jQuery.swap() is undocumented and deprecated" ); + } + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + +var oldData = jQuery.data; + +jQuery.data = function( elem, name, value ) { + var curData; + + // If the name is transformed, look for the un-transformed name in the data object + if ( name && name !== jQuery.camelCase( name ) ) { + curData = jQuery.hasData( elem ) && oldData.call( this, elem ); + if ( curData && name in curData ) { + migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name ); + if ( arguments.length > 2 ) { + curData[ name ] = value; + } + return curData[ name ]; + } + } + + return oldData.apply( this, arguments ); +}; + +var oldTweenRun = jQuery.Tween.prototype.run; + +jQuery.Tween.prototype.run = function( percent ) { + if ( jQuery.easing[ this.easing ].length > 1 ) { + migrateWarn( + "easing function " + + "\"jQuery.easing." + this.easing.toString() + + "\" should use only first argument" + ); + + jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind( + jQuery.easing, + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } + + oldTweenRun.apply( this, arguments ); +}; + +var oldLoad = jQuery.fn.load, + originalFix = jQuery.event.fix; + +jQuery.event.props = []; +jQuery.event.fixHooks = {}; + +jQuery.event.fix = function( originalEvent ) { + var event, + type = originalEvent.type, + fixHook = this.fixHooks[ type ], + props = jQuery.event.props; + + if ( props.length ) { + migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() ); + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + + if ( fixHook && !fixHook._migrated_ ) { + fixHook._migrated_ = true; + migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type ); + if ( ( props = fixHook.props ) && props.length ) { + while ( props.length ) { + jQuery.event.addProp( props.pop() ); + } + } + } + + event = originalFix.call( this, originalEvent ); + + return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event; +}; + +jQuery.each( [ "load", "unload", "error" ], function( _, name ) { + + jQuery.fn[ name ] = function() { + var args = Array.prototype.slice.call( arguments, 0 ); + + // If this is an ajax load() the first arg should be the string URL; + // technically this could also be the "Anything" arg of the event .load() + // which just goes to show why this dumb signature has been deprecated! + // jQuery custom builds that exclude the Ajax module justifiably die here. + if ( name === "load" && typeof args[ 0 ] === "string" ) { + return oldLoad.apply( this, args ); + } + + migrateWarn( "jQuery.fn." + name + "() is deprecated" ); + + args.splice( 0, 0, name ); + if ( arguments.length ) { + return this.on.apply( this, args ); + } + + // Use .triggerHandler here because: + // - load and unload events don't need to bubble, only applied to window or image + // - error event should not bubble to window, although it does pre-1.7 + // See http://bugs.jquery.com/ticket/11820 + this.triggerHandler.apply( this, args ); + return this; + }; + +} ); + +// Trigger "ready" event only once, on document ready +jQuery( function() { + jQuery( document ).triggerHandler( "ready" ); +} ); + +jQuery.event.special.ready = { + setup: function() { + if ( this === document ) { + migrateWarn( "'ready' event is deprecated" ); + } + } +}; + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + migrateWarn( "jQuery.fn.bind() is deprecated" ); + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + migrateWarn( "jQuery.fn.unbind() is deprecated" ); + return this.off( types, null, fn ); + }, + delegate: function( selector, types, data, fn ) { + migrateWarn( "jQuery.fn.delegate() is deprecated" ); + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + migrateWarn( "jQuery.fn.undelegate() is deprecated" ); + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + + +var oldOffset = jQuery.fn.offset; + +jQuery.fn.offset = function() { + var docElem, + elem = this[ 0 ], + origin = { top: 0, left: 0 }; + + if ( !elem || !elem.nodeType ) { + migrateWarn( "jQuery.fn.offset() requires a valid DOM element" ); + return origin; + } + + docElem = ( elem.ownerDocument || document ).documentElement; + if ( !jQuery.contains( docElem, elem ) ) { + migrateWarn( "jQuery.fn.offset() requires an element connected to a document" ); + return origin; + } + + return oldOffset.apply( this, arguments ); +}; + + +var oldParam = jQuery.param; + +jQuery.param = function( data, traditional ) { + var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + + if ( traditional === undefined && ajaxTraditional ) { + + migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" ); + traditional = ajaxTraditional; + } + + return oldParam.call( this, data, traditional ); +}; + +var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack; + +jQuery.fn.andSelf = function() { + migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" ); + return oldSelf.apply( this, arguments ); +}; + + +var oldDeferred = jQuery.Deferred, + tuples = [ + + // Action, add listener, callbacks, .then handlers, final state + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), "rejected" ], + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ) ] + ]; + +jQuery.Deferred = function( func ) { + var deferred = oldDeferred(), + promise = deferred.promise(); + + deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + migrateWarn( "deferred.pipe() is deprecated" ); + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + + // Deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this === promise ? newDefer.promise() : this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + + }; + + if ( func ) { + func.call( deferred, deferred ); + } + + return deferred; +}; + + + +})( jQuery, window ); diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js index 3d9cc3691..940cf553b 100644 --- a/tests/lib/bootstrap.js +++ b/tests/lib/bootstrap.js @@ -1,10 +1,13 @@ ( function() { +var DEFAULT_JQUERY_VERSION = "1.12.4"; + requirejs.config( { paths: { "globalize": "../../../external/globalize/globalize", "globalize/ja-JP": "../../../external/globalize/globalize.culture.ja-JP", "jquery": jqueryUrl(), + "jquery-migrate": migrateUrl(), "jquery-simulate": "../../../external/jquery-simulate/jquery.simulate", "jshint": "../../../external/jshint/jshint", "lib": "../../lib", @@ -68,6 +71,10 @@ function requireTests( dependencies, noBackCompat ) { dependencies.push( "testswarm" ); } + if ( parseUrl().migrate ) { + dependencies.push( "jquery-migrate" ); + } + requireModules( dependencies, function( QUnit ) { QUnit.start(); } ); @@ -82,21 +89,46 @@ function parseUrl() { var current; for ( ; i < length; i++ ) { - current = parts[ i ].split( "=" ); - data[ current[ 0 ] ] = current[ 1 ]; + if ( parts[ i ].match( "=" ) ) { + current = parts[ i ].split( "=" ); + data[ current[ 0 ] ] = current[ 1 ]; + } else { + data[ parts[ i ] ] = true + } } return data; } function jqueryUrl() { - var version = parseUrl().jquery; + var version = parseUrl().jquery || DEFAULT_JQUERY_VERSION; var url; if ( version === "git" ) { url = "http://code.jquery.com/jquery-" + version; } else { - url = "../../../external/jquery-" + ( version || "1.12.4" ) + "/jquery"; + url = "../../../external/jquery-" + version + "/jquery"; + } + + return url; +} + +function migrateUrl() { + var jqueryVersion = parseUrl().jquery || DEFAULT_JQUERY_VERSION; + var url; + + if ( jqueryVersion === "git" ) { + url = "http://code.jquery.com/jquery-migrate-git"; + } else if ( jqueryVersion[ 0 ] === "3" ) { + url = "../../../external/jquery-migrate-3.0.0/jquery-migrate"; + } else if ( jqueryVersion[ 0 ] === "1" || jqueryVersion[ 0 ] === "2" ) { + url = "../../../external/jquery-migrate-1.4.1/jquery-migrate"; + } else if ( jqueryVersion === "custom" ) { + if ( parseUrl().migrate ) { + throw new Error ( "Migrate not currently supported for custom build" ); + } + } else { + throw new Error( "No migrate version known for jQuery " + jqueryVersion ); } return url; diff --git a/tests/lib/qunit.js b/tests/lib/qunit.js index 15f3e96b1..c16d31154 100644 --- a/tests/lib/qunit.js +++ b/tests/lib/qunit.js @@ -36,6 +36,11 @@ QUnit.config.urlConfig.push( { tooltip: "Which jQuery Core version to test against" } ); +QUnit.config.urlConfig.push( { + id: "migrate", + label: "Enable jquery-migrate" +} ); + QUnit.reset = ( function( reset ) { return function() { |