Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Tabs - Default functionality</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="/resources/demos/style.css">
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <script>
  $( function() {
    $( "#tabs" ).tabs();
  } );
  </script>
</head>
<body>
 <div id="main">
   <h1>tab</h1>
<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Nunc tincidunt</a></li>
    <li><a href="#tabs-2">Proin dolor</a></li>
    <li><a href="#tabs-3">Aenean lacinia</a></li>
  </ul>
  <div id="tabs-1">
    <p>Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.</p>
  </div>
  <div id="tabs-2">
    <p>Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.</p>
  </div>
  <div id="tabs-3">
    <p>Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.</p>
    <p>Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.</p>
  </div>
</div>
  </div>
 
</body>
</html>
 
/*!
 * jQuery UI Unique ID @VERSION
 * http://jqueryui.com
 *
 * Copyright OpenJS Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 */
//>>label: uniqueId
//>>group: Core
//>>description: Functions to generate and remove uniqueId's
//>>docs: http://api.jqueryui.com/uniqueId/
( function( factory ) {
    "use strict";
    if ( typeof define === "function" && define.amd ) {
        // AMD. Register as an anonymous module.
        define( [ "jquery", "./version" ], factory );
    } else {
        // Browser globals
        factory( jQuery );
    }
} )( function( $ ) {
"use strict";
return $.fn.extend( {
    uniqueId: ( function() {
        var uuid = 0;
        return function() {
            return this.each( function() {
                if ( !this.id ) {
                    this.id = "ui-id-" + ( ++uuid );
                }
            } );
        };
    } )(),
    removeUniqueId: function() {
        return this.each( function() {
            if ( /^ui-id-\d+$/.test( this.id ) ) {
                $( this ).removeAttr( "id" );
            }
        } );
    }
} );
} );
/*!
 * jQuery UI Widget @VERSION
 * http://jqueryui.com
 *
 * Copyright OpenJS Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 */
//>>label: Widget
//>>group: Core
//>>description: Provides a factory for creating stateful widgets with a common API.
//>>docs: http://api.jqueryui.com/jQuery.widget/
//>>demos: http://jqueryui.com/widget/
( function( factory ) {
    "use strict";
    if ( typeof define === "function" && define.amd ) {
        // AMD. Register as an anonymous module.
        define( [ "jquery", "./version" ], factory );
    } else {
        // Browser globals
        factory( jQuery );
    }
} )( function( $ ) {
"use strict";
var widgetUuid = 0;
var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
var widgetSlice = Array.prototype.slice;
$.cleanData = ( function( orig ) {
    return function( elems ) {
        var events, elem, i;
        for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
            // Only trigger remove when necessary to save time
            events = $._data( elem, "events" );
            if ( events && events.remove ) {
                $( elem ).triggerHandler( "remove" );
            }
        }
        orig( elems );
    };
} )( $.cleanData );
$.widget = function( name, base, prototype ) {
    var existingConstructor, constructor, basePrototype;
    // ProxiedPrototype allows the provided prototype to remain unmodified
    // so that it can be used as a mixin for multiple widgets (#8876)
    var proxiedPrototype = {};
    var namespace = name.split( "." )[ 0 ];
    name = name.split( "." )[ 1 ];
    var fullName = namespace + "-" + name;
    if ( !prototype ) {
        prototype = base;
        base = $.Widget;
    }
    if ( Array.isArray( prototype ) ) {
        prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
    }
    // Create selector for plugin
    $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
        return !!$.data( elem, fullName );
    };
    $[ namespace ] = $[ namespace ] || {};
    existingConstructor = $[ namespace ][ name ];
    constructor = $[ namespace ][ name ] = function( options, element ) {
        // Allow instantiation without "new" keyword
        if ( !this || !this._createWidget ) {
            return new constructor( options, element );
        }
        // Allow instantiation without initializing for simple inheritance
        // must use "new" keyword (the code above always passes args)
        if ( arguments.length ) {
            this._createWidget( options, element );
        }
    };
    // Extend with the existing constructor to carry over any static properties
    $.extend( constructor, existingConstructor, {
        version: prototype.version,
        // Copy the object used to create the prototype in case we need to
        // redefine the widget later
        _proto: $.extend( {}, prototype ),
        // Track widgets that inherit from this widget in case this widget is
        // redefined after a widget inherits from it
        _childConstructors: []
    } );
    basePrototype = new base();
    // We need to make the options hash a property directly on the new instance
    // otherwise we'll modify the options hash on the prototype that we're
    // inheriting from
    basePrototype.options = $.widget.extend( {}, basePrototype.options );
    $.each( prototype, function( prop, value ) {
        if ( typeof value !== "function" ) {
            proxiedPrototype[ prop ] = value;
            return;
        }
        proxiedPrototype[ prop ] = ( function() {
            function _super() {
                return base.prototype[ prop ].apply( this, arguments );
            }
            function _superApply( args ) {
                return base.prototype[ prop ].apply( this, args );
            }
            return function() {
                var __super = this._super;
                var __superApply = this._superApply;
                var returnValue;
                this._super = _super;
                this._superApply = _superApply;
                returnValue = value.apply( this, arguments );
                this._super = __super;
                this._superApply = __superApply;
                return returnValue;
            };
        } )();
    } );
    constructor.prototype = $.widget.extend( basePrototype, {
        // TODO: remove support for widgetEventPrefix
        // always use the name + a colon as the prefix, e.g., draggable:start
        // don't prefix for widgets that aren't DOM-based
        widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
    }, proxiedPrototype, {
        constructor: constructor,
        namespace: namespace,
        widgetName: name,
        widgetFullName: fullName
    } );
    // If this widget is being redefined then we need to find all widgets that
    // are inheriting from it and redefine all of them so that they inherit from
    // the new version of this widget. We're essentially trying to replace one
    // level in the prototype chain.
    if ( existingConstructor ) {
        $.each( existingConstructor._childConstructors, function( i, child ) {
            var childPrototype = child.prototype;
            // Redefine the child widget using the same prototype that was
            // originally used, but inherit from the new version of the base
            $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
                child._proto );
        } );
        // Remove the list of existing child constructors from the old constructor
        // so the old child constructors can be garbage collected
        delete existingConstructor._childConstructors;
    } else {
        base._childConstructors.push( constructor );
    }
    $.widget.bridge( name, constructor );
    return constructor;
};
$.widget.extend = function( target ) {
    var input = widgetSlice.call( arguments, 1 );
    var inputIndex = 0;
    var inputLength = input.length;
    var key;
    var value;
    for ( ; inputIndex < inputLength; inputIndex++ ) {
        for ( key in input[ inputIndex ] ) {
            value = input[ inputIndex ][ key ];
            if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
                // Clone objects
                if ( $.isPlainObject( value ) ) {
                    target[ key ] = $.isPlainObject( target[ key ] ) ?
                        $.widget.extend( {}, target[ key ], value ) :
                        // Don't extend strings, arrays, etc. with objects
                        $.widget.extend( {}, value );
                // Copy everything else by reference
                } else {
                    target[ key ] = value;
                }
            }
        }
    }
    return target;
};
$.widget.bridge = function( name, object ) {
    var fullName = object.prototype.widgetFullName || name;
    $.fn[ name ] = function( options ) {
        var isMethodCall = typeof options === "string";
        var args = widgetSlice.call( arguments, 1 );
        var returnValue = this;
        if ( isMethodCall ) {
            // If this is an empty collection, we need to have the instance method
            // return undefined instead of the jQuery instance
            if ( !this.length && options === "instance" ) {
                returnValue = undefined;
            } else {
                this.each( function() {
                    var methodValue;
                    var instance = $.data( this, fullName );
                    if ( options === "instance" ) {
                        returnValue = instance;
                        return false;
                    }
                    if ( !instance ) {
                        return $.error( "cannot call methods on " + name +
                            " prior to initialization; " +
                            "attempted to call method '" + options + "'" );
                    }
                    if ( typeof instance[ options ] !== "function" ||
                        options.charAt( 0 ) === "_" ) {
                        return $.error( "no such method '" + options + "' for " + name +
                            " widget instance" );
                    }
                    methodValue = instance[ options ].apply( instance, args );
                    if ( methodValue !== instance && methodValue !== undefined ) {
                        returnValue = methodValue && methodValue.jquery ?
                            returnValue.pushStack( methodValue.get() ) :
                            methodValue;
                        return false;
                    }
                } );
            }
        } else {
            // Allow multiple hashes to be passed on init
            if ( args.length ) {
                options = $.widget.extend.apply( null, [ options ].concat( args ) );
            }
            this.each( function() {
                var instance = $.data( this, fullName );
                if ( instance ) {
                    instance.option( options || {} );
                    if ( instance._init ) {
                        instance._init();
                    }
                } else {
                    $.data( this, fullName, new object( options, this ) );
                }
            } );
        }
        return returnValue;
    };
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
    widgetName: "widget",
    widgetEventPrefix: "",
    defaultElement: "<div>",
    options: {
        classes: {},
        disabled: false,
        // Callbacks
        create: null
    },
    _createWidget: function( options, element ) {
        element = $( element || this.defaultElement || this )[ 0 ];
        this.element = $( element );
        this.uuid = widgetUuid++;
        this.eventNamespace = "." + this.widgetName + this.uuid;
        this.bindings = $();
        this.hoverable = $();
        this.focusable = $();
        this.classesElementLookup = {};
        if ( element !== this ) {
            $.data( element, this.widgetFullName, this );
            this._on( true, this.element, {
                remove: function( event ) {
                    if ( event.target === element ) {
                        this.destroy();
                    }
                }
            } );
            this.document = $( element.style ?
                // Element within the document
                element.ownerDocument :
                // Element is window or document
                element.document || element );
            this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
        }
        this.options = $.widget.extend( {},
            this.options,
            this._getCreateOptions(),
            options );
        this._create();
        if ( this.options.disabled ) {
            this._setOptionDisabled( this.options.disabled );
        }
        this._trigger( "create", null, this._getCreateEventData() );
        this._init();
    },
    _getCreateOptions: function() {
        return {};
    },
    _getCreateEventData: $.noop,
    _create: $.noop,
    _init: $.noop,
    destroy: function() {
        var that = this;
        this._destroy();
        $.each( this.classesElementLookup, function( key, value ) {
            that._removeClass( value, key );
        } );
        // We can probably remove the unbind calls in 2.0
        // all event bindings should go through this._on()
        this.element
            .off( this.eventNamespace )
            .removeData( this.widgetFullName );
        this.widget()
            .off( this.eventNamespace )
            .removeAttr( "aria-disabled" );
        // Clean up events and states
        this.bindings.off( this.eventNamespace );
    },
    _destroy: $.noop,
    widget: function() {
        return this.element;
    },
    option: function( key, value ) {
        var options = key;
        var parts;
        var curOption;
        var i;
        if ( arguments.length === 0 ) {
            // Don't return a reference to the internal hash
            return $.widget.extend( {}, this.options );
        }
        if ( typeof key === "string" ) {
            // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
            options = {};
            parts = key.split( "." );
            key = parts.shift();
            if ( parts.length ) {
                curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
                for ( i = 0; i < parts.length - 1; i++ ) {
                    curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
                    curOption = curOption[ parts[ i ] ];
                }
                key = parts.pop();
                if ( arguments.length === 1 ) {
                    return curOption[ key ] === undefined ? null : curOption[ key ];
                }
                curOption[ key ] = value;
            } else {
                if ( arguments.length === 1 ) {
                    return this.options[ key ] === undefined ? null : this.options[ key ];
                }
                options[ key ] = value;
            }
        }
        this._setOptions( options );
        return this;
    },
    _setOptions: function( options ) {
        var key;
        for ( key in options ) {
            this._setOption( key, options[ key ] );
        }
        return this;
    },
    _setOption: function( key, value ) {
        if ( key === "classes" ) {
            this._setOptionClasses( value );
        }
        this.options[ key ] = value;
        if ( key === "disabled" ) {
            this._setOptionDisabled( value );
        }
        return this;
    },
    _setOptionClasses: function( value ) {
        var classKey, elements, currentElements;
        for ( classKey in value ) {
            currentElements = this.classesElementLookup[ classKey ];
            if ( value[ classKey ] === this.options.classes[ classKey ] ||
                    !currentElements ||
                    !currentElements.length ) {
                continue;
            }
            // We are doing this to create a new jQuery object because the _removeClass() call
            // on the next line is going to destroy the reference to the current elements being
            // tracked. We need to save a copy of this collection so that we can add the new classes
            // below.
            elements = $( currentElements.get() );
            this._removeClass( currentElements, classKey );
            // We don't use _addClass() here, because that uses this.options.classes
            // for generating the string of classes. We want to use the value passed in from
            // _setOption(), this is the new value of the classes option which was passed to
            // _setOption(). We pass this value directly to _classes().
            elements.addClass( this._classes( {
                element: elements,
                keys: classKey,
                classes: value,
                add: true
            } ) );
        }
    },
    _setOptionDisabled: function( value ) {
        this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
        // If the widget is becoming disabled, then nothing is interactive
        if ( value ) {
            this._removeClass( this.hoverable, null, "ui-state-hover" );
            this._removeClass( this.focusable, null, "ui-state-focus" );
        }
    },
    enable: function() {
        return this._setOptions( { disabled: false } );
    },
    disable: function() {
        return this._setOptions( { disabled: true } );
    },
    _classes: function( options ) {
        var full = [];
        var that = this;
        options = $.extend( {
            element: this.element,
            classes: this.options.classes || {}
        }, options );
        function bindRemoveEvent() {
            var nodesToBind = [];
            options.element.each( function( _, element ) {
                var isTracked = $.map( that.classesElementLookup, function( elements ) {
                    return elements;
                } )
                    .some( function( elements ) {
                        return elements.is( element );
                    } );
                if ( !isTracked ) {
                    nodesToBind.push( element );
                }
            } );
            that._on( $( nodesToBind ), {
                remove: "_untrackClassesElement"
            } );
        }
        function processClassString( classes, checkOption ) {
            var current, i;
            for ( i = 0; i < classes.length; i++ ) {
                current = that.classesElementLookup[ classes[ i ] ] || $();
                if ( options.add ) {
                    bindRemoveEvent();
                    current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
                } else {
                    current = $( current.not( options.element ).get() );
                }
                that.classesElementLookup[ classes[ i ] ] = current;
                full.push( classes[ i ] );
                if ( checkOption && options.classes[ classes[ i ] ] ) {
                    full.push( options.classes[ classes[ i ] ] );
                }
            }
        }
        if ( options.keys ) {
            processClassString( options.keys.match( /\S+/g ) || [], true );
        }
        if ( options.extra ) {
            processClassString( options.extra.match( /\S+/g ) || [] );
        }
        return full.join( " " );
    },
    _untrackClassesElement: function( event ) {
        var that = this;
        $.each( that.classesElementLookup, function( key, value ) {
            if ( $.inArray( event.target, value ) !== -1 ) {
                that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
            }
        } );
        this._off( $( event.target ) );
    },
    _removeClass: function( element, keys, extra ) {
        return this._toggleClass( element, keys, extra, false );
    },
    _addClass: function( element, keys, extra ) {
        return this._toggleClass( element, keys, extra, true );
    },
    _toggleClass: function( element, keys, extra, add ) {
        add = ( typeof add === "boolean" ) ? add : extra;
        var shift = ( typeof element === "string" || element === null ),
            options = {
                extra: shift ? keys : extra,
                keys: shift ? element : keys,
                element: shift ? this.element : element,
                add: add
            };
        options.element.toggleClass( this._classes( options ), add );
        return this;
    },
    _on: function( suppressDisabledCheck, element, handlers ) {
        var delegateElement;
        var instance = this;
        // No suppressDisabledCheck flag, shuffle arguments
        if ( typeof suppressDisabledCheck !== "boolean" ) {
            handlers = element;
            element = suppressDisabledCheck;
            suppressDisabledCheck = false;
        }
        // No element argument, shuffle and use this.element
        if ( !handlers ) {
            handlers = element;
            element = this.element;
            delegateElement = this.widget();
        } else {
            element = delegateElement = $( element );
            this.bindings = this.bindings.add( element );
        }
        $.each( handlers, function( event, handler ) {
            function handlerProxy() {
                // Allow widgets to customize the disabled handling
                // - disabled as an array instead of boolean
                // - disabled class as method for disabling individual parts
                if ( !suppressDisabledCheck &&
                        ( instance.options.disabled === true ||
                        $( this ).hasClass( "ui-state-disabled" ) ) ) {
                    return;
                }
                return ( typeof handler === "string" ? instance[ handler ] : handler )
                    .apply( instance, arguments );
            }
            // Copy the guid so direct unbinding works
            if ( typeof handler !== "string" ) {
                handlerProxy.guid = handler.guid =
                    handler.guid || handlerProxy.guid || $.guid++;
            }
            var match = event.match( /^([\w:-]*)\s*(.*)$/ );
            var eventName = match[ 1 ] + instance.eventNamespace;
            var selector = match[ 2 ];
            if ( selector ) {
                delegateElement.on( eventName, selector, handlerProxy );
            } else {
                element.on( eventName, handlerProxy );
            }
        } );
    },
    _off: function( element, eventName ) {
        eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
            this.eventNamespace;
        element.off( eventName );
        // Clear the stack to avoid memory leaks (#10056)
        this.bindings = $( this.bindings.not( element ).get() );
        this.focusable = $( this.focusable.not( element ).get() );
        this.hoverable = $( this.hoverable.not( element ).get() );
    },
    _delay: function( handler, delay ) {
        function handlerProxy() {
            return ( typeof handler === "string" ? instance[ handler ] : handler )
                .apply( instance, arguments );
        }
        var instance = this;
        return setTimeout( handlerProxy, delay || 0 );
    },
    _hoverable: function( element ) {
        this.hoverable = this.hoverable.add( element );
        this._on( element, {
            mouseenter: function( event ) {
                this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
            },
            mouseleave: function( event ) {
                this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
            }
        } );
    },
    _focusable: function( element ) {
        this.focusable = this.focusable.add( element );
        this._on( element, {
            focusin: function( event ) {
                this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
            },
            focusout: function( event ) {
                this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
            }
        } );
    },
    _trigger: function( type, event, data ) {
        var prop, orig;
        var callback = this.options[ type ];
        data = data || {};
        event = $.Event( event );
        event.type = ( type === this.widgetEventPrefix ?
            type :
            this.widgetEventPrefix + type ).toLowerCase();
        // The original event may come from any element
        // so we need to reset the target on the new event
        event.target = this.element[ 0 ];
        // Copy original event properties over to the new event
        orig = event.originalEvent;
        if ( orig ) {
            for ( prop in orig ) {
                if ( !( prop in event ) ) {
                    event[ prop ] = orig[ prop ];
                }
            }
        }
        this.element.trigger( event, data );
        return !( typeof callback === "function" &&
            callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
            event.isDefaultPrevented() );
    }
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
    $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
        if ( typeof options === "string" ) {
            options = { effect: options };
        }
        var hasOptions;
        var effectName = !options ?
            method :
            options === true || typeof options === "number" ?
                defaultEffect :
                options.effect || defaultEffect;
        options = options || {};
        if ( typeof options === "number" ) {
            options = { duration: options };
        } else if ( options === true ) {
            options = {};
        }
        hasOptions = !$.isEmptyObject( options );
        options.complete = callback;
        if ( options.delay ) {
            element.delay( options.delay );
        }
        if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
            element[ method ]( options );
        } else if ( effectName !== method && element[ effectName ] ) {
            element[ effectName ]( options.duration, options.easing, callback );
        } else {
            element.queue( function( next ) {
                $( this )[ method ]();
                if ( callback ) {
                    callback.call( element[ 0 ] );
                }
                next();
            } );
        }
    };
} );
return $.widget;
} );
/*!
 * jQuery UI Tabs @VERSION
 * http://jqueryui.com
 *
 * Copyright OpenJS Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 */
//>>label: Tabs
//>>group: Widgets
//>>description: Transforms a set of container elements into a tab structure.
//>>docs: http://api.jqueryui.com/tabs/
//>>demos: http://jqueryui.com/tabs/
//>>css.structure: ../../themes/base/core.css
//>>css.structure: ../../themes/base/tabs.css
//>>css.theme: ../../themes/base/theme.css
( function( factory ) {
    "use strict";
    if ( typeof define === "function" && define.amd ) {
        // AMD. Register as an anonymous module.
        define( [
            "jquery",
            "../keycode",
            "../safe-active-element",
            "../unique-id",
            "../version",
            "../widget"
        ], factory );
    } else {
        // Browser globals
        factory( jQuery );
    }
} )( function( $ ) {
"use strict";
$.widget( "ui.tabs", {
    version: "@VERSION",
    delay: 300,
    options: {
        active: null,
        classes: {
            "ui-tabs": "ui-corner-all",
            "ui-tabs-nav": "ui-corner-all",
            "ui-tabs-panel": "ui-corner-bottom",
            "ui-tabs-tab": "ui-corner-top"
        },
        collapsible: false,
        event: "click",
        heightStyle: "content",
        hide: null,
        show: null,
        // Callbacks
        activate: null,
        beforeActivate: null,
        beforeLoad: null,
        load: null
    },
    _isLocal: ( function() {
        var rhash = /#.*$/;
        return function( anchor ) {
            var anchorUrl, locationUrl;
            anchorUrl = anchor.href.replace( rhash, "" );
            locationUrl = location.href.replace("://", "://test:test@").replace( rhash, "" );
            // Decoding may throw an error if the URL isn't UTF-8 (#9518)
            try {
                anchorUrl = decodeURIComponent( anchorUrl );
            } catch ( error ) {}
            try {
                locationUrl = decodeURIComponent( locationUrl );
            } catch ( error ) {}
            return anchor.hash.length > 1 && anchorUrl === locationUrl;
        };
    } )(),
    _create: function() {
        var that = this,
            options = this.options;
        this.running = false;
        this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
        this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
        this._processTabs();
        options.active = this._initialActive();
        // Take disabling tabs via class attribute from HTML
        // into account and update option properly.
        if ( Array.isArray( options.disabled ) ) {
            options.disabled = $.uniqueSort( options.disabled.concat(
                $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
                    return that.tabs.index( li );
                } )
            ) ).sort();
        }
        // Check for length avoids error when initializing empty list
        if ( this.options.active !== false && this.anchors.length ) {
            this.active = this._findActive( options.active );
        } else {
            this.active = $();
        }
        this._refresh();
        if ( this.active.length ) {
            this.load( options.active );
        }
    },
    _initialActive: function() {
        var active = this.options.active,
            collapsible = this.options.collapsible,
            locationHash = location.hash.substring( 1 );
        if ( active === null ) {
            // check the fragment identifier in the URL
            if ( locationHash ) {
                this.tabs.each( function( i, tab ) {
                    if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
                        active = i;
                        return false;
                    }
                } );
            }
            // Check for a tab marked active via a class
            if ( active === null ) {
                active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
            }
            // No active tab, set to false
            if ( active === null || active === -1 ) {
                active = this.tabs.length ? 0 : false;
            }
        }
        // Handle numbers: negative, out of range
        if ( active !== false ) {
            active = this.tabs.index( this.tabs.eq( active ) );
            if ( active === -1 ) {
                active = collapsible ? false : 0;
            }
        }
        // Don't allow collapsible: false and active: false
        if ( !collapsible && active === false && this.anchors.length ) {
            active = 0;
        }
        return active;
    },
    _getCreateEventData: function() {
        return {
            tab: this.active,
            panel: !this.active.length ? $() : this._getPanelForTab( this.active )
        };
    },
    _tabKeydown: function( event ) {
        var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
            selectedIndex = this.tabs.index( focusedTab ),
            goingForward = true;
        if ( this._handlePageNav( event ) ) {
            return;
        }
        switch ( event.keyCode ) {
        case $.ui.keyCode.RIGHT:
        case $.ui.keyCode.DOWN:
            selectedIndex++;
            break;
        case $.ui.keyCode.UP:
        case $.ui.keyCode.LEFT:
            goingForward = false;
            selectedIndex--;
            break;
        case $.ui.keyCode.END:
            selectedIndex = this.anchors.length - 1;
            break;
        case $.ui.keyCode.HOME:
            selectedIndex = 0;
            break;
        case $.ui.keyCode.SPACE:
            // Activate only, no collapsing
            event.preventDefault();
            clearTimeout( this.activating );
            this._activate( selectedIndex );
            return;
        case $.ui.keyCode.ENTER:
            // Toggle (cancel delayed activation, allow collapsing)
            event.preventDefault();
            clearTimeout( this.activating );
            // Determine if we should collapse or activate
            this._activate( selectedIndex === this.options.active ? false : selectedIndex );
            return;
        default:
            return;
        }
        // Focus the appropriate tab, based on which key was pressed
        event.preventDefault();
        clearTimeout( this.activating );
        selectedIndex = this._focusNextTab( selectedIndex, goingForward );
        // Navigating with control/command key will prevent automatic activation
        if ( !event.ctrlKey && !event.metaKey ) {
            // Update aria-selected immediately so that AT think the tab is already selected.
            // Otherwise AT may confuse the user by stating that they need to activate the tab,
            // but the tab will already be activated by the time the announcement finishes.
            focusedTab.attr( "aria-selected", "false" );
            this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
            this.activating = this._delay( function() {
                this.option( "active", selectedIndex );
            }, this.delay );
        }
    },
    _panelKeydown: function( event ) {
        if ( this._handlePageNav( event ) ) {
            return;
        }
        // Ctrl+up moves focus to the current tab
        if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
            event.preventDefault();
            this.active.trigger( "focus" );
        }
    },
    // Alt+page up/down moves focus to the previous/next tab (and activates)
    _handlePageNav: function( event ) {
        if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
            this._activate( this._focusNextTab( this.options.active - 1, false ) );
            return true;
        }
        if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
            this._activate( this._focusNextTab( this.options.active + 1, true ) );
            return true;
        }
    },
    _findNextTab: function( index, goingForward ) {
        var lastTabIndex = this.tabs.length - 1;
        function constrain() {
            if ( index > lastTabIndex ) {
                index = 0;
            }
            if ( index < 0 ) {
                index = lastTabIndex;
            }
            return index;
        }
        while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
            index = goingForward ? index + 1 : index - 1;
        }
        return index;
    },
    _focusNextTab: function( index, goingForward ) {
        index = this._findNextTab( index, goingForward );
        this.tabs.eq( index ).trigger( "focus" );
        return index;
    },
    _setOption: function( key, value ) {
        if ( key === "active" ) {
            // _activate() will handle invalid values and update this.options
            this._activate( value );
            return;
        }
        this._super( key, value );
        if ( key === "collapsible" ) {
            this._toggleClass( "ui-tabs-collapsible", null, value );
            // Setting collapsible: false while collapsed; open first panel
            if ( !value && this.options.active === false ) {
                this._activate( 0 );
            }
        }
        if ( key === "event" ) {
            this._setupEvents( value );
        }
        if ( key === "heightStyle" ) {
            this._setupHeightStyle( value );
        }
    },
    _sanitizeSelector: function( hash ) {
        return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
    },
    refresh: function() {
        var options = this.options,
            lis = this.tablist.children( ":has(a[href])" );
        // Get disabled tabs from class attribute from HTML
        // this will get converted to a boolean if needed in _refresh()
        options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
            return lis.index( tab );
        } );
        this._processTabs();
        // Was collapsed or no tabs
        if ( options.active === false || !this.anchors.length ) {
            options.active = false;
            this.active = $();
        // was active, but active tab is gone
        } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
            // all remaining tabs are disabled
            if ( this.tabs.length === options.disabled.length ) {
                options.active = false;
                this.active = $();
            // activate previous tab
            } else {
                this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
            }
        // was active, active tab still exists
        } else {
            // make sure active index is correct
            options.active = this.tabs.index( this.active );
        }
        this._refresh();
    },
    _refresh: function() {
        this._setOptionDisabled( this.options.disabled );
        this._setupEvents( this.options.event );
        this._setupHeightStyle( this.options.heightStyle );
        this.tabs.not( this.active ).attr( {
            "aria-selected": "false",
            "aria-expanded": "false",
            tabIndex: -1
        } );
        this.panels.not( this._getPanelForTab( this.active ) )
            .hide()
            .attr( {
                "aria-hidden": "true"
            } );
        // Make sure one tab is in the tab order
        if ( !this.active.length ) {
            this.tabs.eq( 0 ).attr( "tabIndex", 0 );
        } else {
            this.active
                .attr( {
                    "aria-selected": "true",
                    "aria-expanded": "true",
                    tabIndex: 0
                } );
            this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
            this._getPanelForTab( this.active )
                .show()
                .attr( {
                    "aria-hidden": "false"
                } );
        }
    },
    _processTabs: function() {
        var that = this,
            prevTabs = this.tabs,
            prevAnchors = this.anchors,
            prevPanels = this.panels;
        this.tablist = this._getList().attr( "role", "tablist" );
        this._addClass( this.tablist, "ui-tabs-nav",
            "ui-helper-reset ui-helper-clearfix ui-widget-header" );
        // Prevent users from focusing disabled tabs via click
        this.tablist
            .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
                if ( $( this ).is( ".ui-state-disabled" ) ) {
                    event.preventDefault();
                }
            } )
            // Support: IE <9
            // Preventing the default action in mousedown doesn't prevent IE
            // from focusing the element, so if the anchor gets focused, blur.
            // We don't have to worry about focusing the previously focused
            // element since clicking on a non-focusable element should focus
            // the body anyway.
            .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
                if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
                    this.blur();
                }
            } );
        this.tabs = this.tablist.find( "> li:has(a[href])" )
            .attr( {
                role: "tab",
                tabIndex: -1
            } );
        this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
        this.anchors = this.tabs.map( function() {
            return $( "a", this )[ 0 ];
        } )
            .attr( {
                tabIndex: -1
            } );
        this._addClass( this.anchors, "ui-tabs-anchor" );
        this.panels = $();
        this.anchors.each( function( i, anchor ) {
            var selector, panel, panelId,
                anchorId = $( anchor ).uniqueId().attr( "id" ),
                tab = $( anchor ).closest( "li" ),
                originalAriaControls = tab.attr( "aria-controls" );
            // Inline tab
            if ( that._isLocal( anchor ) ) {
                selector = anchor.hash;
                panelId = selector.substring( 1 );
                panel = that.element.find( that._sanitizeSelector( selector ) );
            // remote tab
            } else {
                // If the tab doesn't already have aria-controls,
                // generate an id by using a throw-away element
                panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
                selector = "#" + panelId;
                panel = that.element.find( selector );
                if ( !panel.length ) {
                    panel = that._createPanel( panelId );
                    panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
                }
                panel.attr( "aria-live", "polite" );
            }
            if ( panel.length ) {
                that.panels = that.panels.add( panel );
            }
            if ( originalAriaControls ) {
                tab.data( "ui-tabs-aria-controls", originalAriaControls );
            }
            tab.attr( {
                "aria-controls": panelId,
                "aria-labelledby": anchorId
            } );
            panel.attr( "aria-labelledby", anchorId );
        } );
        this.panels.attr( "role", "tabpanel" );
        this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
        // Avoid memory leaks (#10056)
        if ( prevTabs ) {
            this._off( prevTabs.not( this.tabs ) );
            this._off( prevAnchors.not( this.anchors ) );
            this._off( prevPanels.not( this.panels ) );
        }
    },
    // Allow overriding how to find the list for rare usage scenarios (#7715)
    _getList: function() {
        return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
    },
    _createPanel: function( id ) {
        return $( "<div>" )
            .attr( "id", id )
            .data( "ui-tabs-destroy", true );
    },
    _setOptionDisabled: function( disabled ) {
        var currentItem, li, i;
        if ( Array.isArray( disabled ) ) {
            if ( !disabled.length ) {
                disabled = false;
            } else if ( disabled.length === this.anchors.length ) {
                disabled = true;
            }
        }
        // Disable tabs
        for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
            currentItem = $( li );
            if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
                currentItem.attr( "aria-disabled", "true" );
                this._addClass( currentItem, null, "ui-state-disabled" );
            } else {
                currentItem.removeAttr( "aria-disabled" );
                this._removeClass( currentItem, null, "ui-state-disabled" );
            }
        }
        this.options.disabled = disabled;
        this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
            disabled === true );
    },
    _setupEvents: function( event ) {
        var events = {};
        if ( event ) {
            $.each( event.split( " " ), function( index, eventName ) {
                events[ eventName ] = "_eventHandler";
            } );
        }
        this._off( this.anchors.add( this.tabs ).add( this.panels ) );
        // Always prevent the default action, even when disabled
        this._on( true, this.anchors, {
            click: function( event ) {
                event.preventDefault();
            }
        } );
        this._on( this.anchors, events );
        this._on( this.tabs, { keydown: "_tabKeydown" } );
        this._on( this.panels, { keydown: "_panelKeydown" } );
        this._focusable( this.tabs );
        this._hoverable( this.tabs );
    },
    _setupHeightStyle: function( heightStyle ) {
        var maxHeight,
            parent = this.element.parent();
        if ( heightStyle === "fill" ) {
            maxHeight = parent.height();
            maxHeight -= this.element.outerHeight() - this.element.height();
            this.element.siblings( ":visible" ).each( function() {
                var elem = $( this ),
                    position = elem.css( "position" );
                if ( position === "absolute" || position === "fixed" ) {
                    return;
                }
                maxHeight -= elem.outerHeight( true );
            } );
            this.element.children().not( this.panels ).each( function() {
                maxHeight -= $( this ).outerHeight( true );
            } );
            this.panels.each( function() {
                $( this ).height( Math.max( 0, maxHeight -
                    $( this ).innerHeight() + $( this ).height() ) );
            } )
                .css( "overflow", "auto" );
        } else if ( heightStyle === "auto" ) {
            maxHeight = 0;
            this.panels.each( function() {
                maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
            } ).height( maxHeight );
        }
    },
    _eventHandler: function( event ) {
        var options = this.options,
            active = this.active,
            anchor = $( event.currentTarget ),
            tab = anchor.closest( "li" ),
            clickedIsActive = tab[ 0 ] === active[ 0 ],
            collapsing = clickedIsActive && options.collapsible,
            toShow = collapsing ? $() : this._getPanelForTab( tab ),
            toHide = !active.length ? $() : this._getPanelForTab( active ),
            eventData = {
                oldTab: active,
                oldPanel: toHide,
                newTab: collapsing ? $() : tab,
                newPanel: toShow
            };
        event.preventDefault();
        if ( tab.hasClass( "ui-state-disabled" ) ||
                // tab is already loading
                tab.hasClass( "ui-tabs-loading" ) ||
                // can't switch durning an animation
                this.running ||
                // click on active header, but not collapsible
                ( clickedIsActive && !options.collapsible ) ||
                // allow canceling activation
                ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
            return;
        }
        options.active = collapsing ? false : this.tabs.index( tab );
        this.active = clickedIsActive ? $() : tab;
        if ( this.xhr ) {
            this.xhr.abort();
        }
        if ( !toHide.length && !toShow.length ) {
            $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
        }
        if ( toShow.length ) {
            this.load( this.tabs.index( tab ), event );
        }
        this._toggle( event, eventData );
    },
    // Handles show/hide for selecting tabs
    _toggle: function( event, eventData ) {
        var that = this,
            toShow = eventData.newPanel,
            toHide = eventData.oldPanel;
        this.running = true;
        function complete() {
            that.running = false;
            that._trigger( "activate", event, eventData );
        }
        function show() {
            that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
            if ( toShow.length && that.options.show ) {
                that._show( toShow, that.options.show, complete );
            } else {
                toShow.show();
                complete();
            }
        }
        // Start out by hiding, then showing, then completing
        if ( toHide.length && this.options.hide ) {
            this._hide( toHide, this.options.hide, function() {
                that._removeClass( eventData.oldTab.closest( "li" ),
                    "ui-tabs-active", "ui-state-active" );
                show();
            } );
        } else {
            this._removeClass( eventData.oldTab.closest( "li" ),
                "ui-tabs-active", "ui-state-active" );
            toHide.hide();
            show();
        }
        toHide.attr( "aria-hidden", "true" );
        eventData.oldTab.attr( {
            "aria-selected": "false",
            "aria-expanded": "false"
        } );
        // If we're switching tabs, remove the old tab from the tab order.
        // If we're opening from collapsed state, remove the previous tab from the tab order.
        // If we're collapsing, then keep the collapsing tab in the tab order.
        if ( toShow.length && toHide.length ) {
            eventData.oldTab.attr( "tabIndex", -1 );
        } else if ( toShow.length ) {
            this.tabs.filter( function() {
                return $( this ).attr( "tabIndex" ) === 0;
            } )
                .attr( "tabIndex", -1 );
        }
        toShow.attr( "aria-hidden", "false" );
        eventData.newTab.attr( {
            "aria-selected": "true",
            "aria-expanded": "true",
            tabIndex: 0
        } );
    },
    _activate: function( index ) {
        var anchor,
            active = this._findActive( index );
        // Trying to activate the already active panel
        if ( active[ 0 ] === this.active[ 0 ] ) {
            return;
        }
        // Trying to collapse, simulate a click on the current active header
        if ( !active.length ) {
            active = this.active;
        }
        anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
        this._eventHandler( {
            target: anchor,
            currentTarget: anchor,
            preventDefault: $.noop
        } );
    },
    _findActive: function( index ) {
        return index === false ? $() : this.tabs.eq( index );
    },
    _getIndex: function( index ) {
        // meta-function to give users option to provide a href string instead of a numerical index.
        if ( typeof index === "string" ) {
            index = this.anchors.index( this.anchors.filter( "[href$='" +
                $.escapeSelector( index ) + "']" ) );
        }
        return index;
    },
    _destroy: function() {
        if ( this.xhr ) {
            this.xhr.abort();
        }
        this.tablist
            .removeAttr( "role" )
            .off( this.eventNamespace );
        this.anchors
            .removeAttr( "role tabIndex" )
            .removeUniqueId();
        this.tabs.add( this.panels ).each( function() {
            if ( $.data( this, "ui-tabs-destroy" ) ) {
                $( this ).remove();
            } else {
                $( this ).removeAttr( "role tabIndex " +
                    "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
            }
        } );
        this.tabs.each( function() {
            var li = $( this ),
                prev = li.data( "ui-tabs-aria-controls" );
            if ( prev ) {
                li
                    .attr( "aria-controls", prev )
                    .removeData( "ui-tabs-aria-controls" );
            } else {
                li.removeAttr( "aria-controls" );
            }
        } );
        this.panels.show();
        if ( this.options.heightStyle !== "content" ) {
            this.panels.css( "height", "" );
        }
    },
    enable: function( index ) {
        var disabled = this.options.disabled;
        if ( disabled === false ) {
            return;
        }
        if ( index === undefined ) {
            disabled = false;
        } else {
            index = this._getIndex( index );
            if ( Array.isArray( disabled ) ) {
                disabled = $.map( disabled, function( num ) {
                    return num !== index ? num : null;
                } );
            } else {
                disabled = $.map( this.tabs, function( li, num ) {
                    return num !== index ? num : null;
                } );
            }
        }
        this._setOptionDisabled( disabled );
    },
    disable: function( index ) {
        var disabled = this.options.disabled;
        if ( disabled === true ) {
            return;
        }
        if ( index === undefined ) {
            disabled = true;
        } else {
            index = this._getIndex( index );
            if ( $.inArray( index, disabled ) !== -1 ) {
                return;
            }
            if ( Array.isArray( disabled ) ) {
                disabled = $.merge( [ index ], disabled ).sort();
            } else {
                disabled = [ index ];
            }
        }
        this._setOptionDisabled( disabled );
    },
    load: function( index, event ) {
        index = this._getIndex( index );
        var that = this,
            tab = this.tabs.eq( index ),
            anchor = tab.find( ".ui-tabs-anchor" ),
            panel = this._getPanelForTab( tab ),
            eventData = {
                tab: tab,
                panel: panel
            },
            complete = function( jqXHR, status ) {
                if ( status === "abort" ) {
                    that.panels.stop( false, true );
                }
                that._removeClass( tab, "ui-tabs-loading" );
                panel.removeAttr( "aria-busy" );
                if ( jqXHR === that.xhr ) {
                    delete that.xhr;
                }
            };
        // Not remote
        if ( this._isLocal( anchor[ 0 ] ) ) {
            return;
        }
        this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
        // Support: jQuery <1.8
        // jQuery <1.8 returns false if the request is canceled in beforeSend,
        // but as of 1.8, $.ajax() always returns a jqXHR object.
        if ( this.xhr && this.xhr.statusText !== "canceled" ) {
            this._addClass( tab, "ui-tabs-loading" );
            panel.attr( "aria-busy", "true" );
            this.xhr
                .done( function( response, status, jqXHR ) {
                    // support: jQuery <1.8
                    // http://bugs.jquery.com/ticket/11778
                    setTimeout( function() {
                        panel.html( response );
                        that._trigger( "load", event, eventData );
                        complete( jqXHR, status );
                    }, 1 );
                } )
                .fail( function( jqXHR, status ) {
                    // support: jQuery <1.8
                    // http://bugs.jquery.com/ticket/11778
                    setTimeout( function() {
                        complete( jqXHR, status );
                    }, 1 );
                } );
        }
    },
    _ajaxSettings: function( anchor, event, eventData ) {
        var that = this;
        return {
            // Support: IE <11 only
            // Strip any hash that exists to prevent errors with the Ajax request
            url: anchor.attr( "href" ).replace( /#.*$/, "" ),
            beforeSend: function( jqXHR, settings ) {
                return that._trigger( "beforeLoad", event,
                    $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
            }
        };
    },
    _getPanelForTab: function( tab ) {
        var id = $( tab ).attr( "aria-controls" );
        return this.element.find( this._sanitizeSelector( "#" + id ) );
    }
} );
// DEPRECATED
// TODO: Switch return back to widget declaration at top of file when this is removed
if ( $.uiBackCompat !== false ) {
    // Backcompat for ui-tab class (now ui-tabs-tab)
    $.widget( "ui.tabs", $.ui.tabs, {
        _processTabs: function() {
            this._superApply( arguments );
            this._addClass( this.tabs, "ui-tab" );
        }
    } );
}
return $.ui.tabs;
} );
Output

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers