PageSourceSearch

https://www.zee5.com/global/blog/wp-includes/js/jquery/ui/tabs.js?ver=1.14.2

js zee5.com collected 2026-09-24 09:06:10 UTC 23,498 bytes, 913 lines download raw bytes

vendor: 23,498 bytes, lines 1-913
1/*!
2 * jQuery UI Tabs 1.14.2
3 * https://jqueryui.com
4 *
5 * Copyright OpenJS Foundation and other contributors
6 * Released under the MIT license.
7 * https://jquery.org/license
8 */
9
10//>>label: Tabs
11//>>group: Widgets
12//>>description: Transforms a set of container elements into a tab structure.
13//>>docs: https://api.jqueryui.com/tabs/
14//>>demos: https://jqueryui.com/tabs/
15//>>css.structure: ../../themes/base/core.css
16//>>css.structure: ../../themes/base/tabs.css
17//>>css.theme: ../../themes/base/theme.css
18
19( function( factory ) {
20	"use strict";
21
22	if ( typeof define === "function" && define.amd ) {
23
24		// AMD. Register as an anonymous module.
25		define( [
26			"jquery",
27			"../keycode",
28			"../unique-id",
29			"../version",
30			"../widget"
31		], factory );
32	} else {
33
34		// Browser globals
35		factory( jQuery );
36	}
37} )( function( $ ) {
38"use strict";
39
40$.widget( "ui.tabs", {
41	version: "1.14.2",
42	delay: 300,
43	options: {
44		active: null,
45		classes: {
46			"ui-tabs": "ui-corner-all",
47			"ui-tabs-nav": "ui-corner-all",
48			"ui-tabs-panel": "ui-corner-bottom",
49			"ui-tabs-tab": "ui-corner-top"
50		},
51		collapsible: false,
52		event: "click",
53		heightStyle: "content",
54		hide: null,
55		show: null,
56
57		// Callbacks
58		activate: null,
59		beforeActivate: null,
60		beforeLoad: null,
61		load: null
62	},
63
64	_isLocal: function( anchor ) {
65		var anchorUrl = new URL( anchor.href ),
66			locationUrl = new URL( location.href );
67
68		return anchor.hash.length > 1 &&
69
70			// `href` may contain a hash but also username & password;
71			// we want to ignore them, so we check the three fields
72			// below instead.
73			anchorUrl.origin === locationUrl.origin &&
74			anchorUrl.pathname === locationUrl.pathname &&
75			anchorUrl.search === locationUrl.search;
76	},
77
78	_create: function() {
79		var that = this,
80			options = this.options;
81
82		this.running = false;
83
84		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
85		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
86
87		this._processTabs();
88		options.active = this._initialActive();
89
90		// Take disabling tabs via class attribute from HTML
91		// into account and update option properly.
92		if ( Array.isArray( options.disabled ) ) {
93			options.disabled = $.uniqueSort( options.disabled.concat(
94				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
95					return that.tabs.index( li );
96				} )
97			) ).sort();
98		}
99
100		// Check for length avoids error when initializing empty list
101		if ( this.options.active !== false && this.anchors.length ) {
102			this.active = this._findActive( options.active );
103		} else {
104			this.active = $();
105		}
106
107		this._refresh();
108
109		if ( this.active.length ) {
110			this.load( options.active );
111		}
112	},
113
114	_initialActive: function() {
115		var active = this.options.active,
116			collapsible = this.options.collapsible,
117			locationHash = location.hash.substring( 1 ),
118			locationHashDecoded = decodeURIComponent( locationHash );
119
120		if ( active === null ) {
121
122			// check the fragment identifier in the URL
123			if ( locationHash ) {
124				this.tabs.each( function( i, tab ) {
125					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
126						active = i;
127						return false;
128					}
129				} );
130
131				// If not found, decode the hash & try again.
132				// See the comment in `_processTabs` under the `_isLocal` check
133				// for more information.
134				if ( active === null ) {
135					this.tabs.each( function( i, tab ) {
136						if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
137							active = i;
138							return false;
139						}
140					} );
141				}
142			}
143
144			// Check for a tab marked active via a class
145			if ( active === null ) {
146				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
147			}
148
149			// No active tab, set to false
150			if ( active === null || active === -1 ) {
151				active = this.tabs.length ? 0 : false;
152			}
153		}
154
155		// Handle numbers: negative, out of range
156		if ( active !== false ) {
157			active = this.tabs.index( this.tabs.eq( active ) );
158			if ( active === -1 ) {
159				active = collapsible ? false : 0;
160			}
161		}
162
163		// Don't allow collapsible: false and active: false
164		if ( !collapsible && active === false && this.anchors.length ) {
165			active = 0;
166		}
167
168		return active;
169	},
170
171	_getCreateEventData: function() {
172		return {
173			tab: this.active,
174			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
175		};
176	},
177
178	_tabKeydown: function( event ) {
179		var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ),
180			selectedIndex = this.tabs.index( focusedTab ),
181			goingForward = true;
182
183		if ( this._handlePageNav( event ) ) {
184			return;
185		}
186
187		switch ( event.keyCode ) {
188		case $.ui.keyCode.RIGHT:
189		case $.ui.keyCode.DOWN:
190			selectedIndex++;
191			break;
192		case $.ui.keyCode.UP:
193		case $.ui.keyCode.LEFT:
194			goingForward = false;
195			selectedIndex--;
196			break;
197		case $.ui.keyCode.END:
198			selectedIndex = this.anchors.length - 1;
199			break;
200		case $.ui.keyCode.HOME:
201			selectedIndex = 0;
202			break;
203		case $.ui.keyCode.SPACE:
204
205			// Activate only, no collapsing
206			event.preventDefault();
207			clearTimeout( this.activating );
208			this._activate( selectedIndex );
209			return;
210		case $.ui.keyCode.ENTER:
211
212			// Toggle (cancel delayed activation, allow collapsing)
213			event.preventDefault();
214			clearTimeout( this.activating );
215
216			// Determine if we should collapse or activate
217			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
218			return;
219		default:
220			return;
221		}
222
223		// Focus the appropriate tab, based on which key was pressed
224		event.preventDefault();
225		clearTimeout( this.activating );
226		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
227
228		// Navigating with control/command key will prevent automatic activation
229		if ( !event.ctrlKey && !event.metaKey ) {
230
231			// Update aria-selected immediately so that AT think the tab is already selected.
232			// Otherwise AT may confuse the user by stating that they need to activate the tab,
233			// but the tab will already be activated by the time the announcement finishes.
234			focusedTab.attr( "aria-selected", "false" );
235			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
236
237			this.activating = this._delay( function() {
238				this.option( "active", selectedIndex );
239			}, this.delay );
240		}
241	},
242
243	_panelKeydown: function( event ) {
244		if ( this._handlePageNav( event ) ) {
245			return;
246		}
247
248		// Ctrl+up moves focus to the current tab
249		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
250			event.preventDefault();
251			this.active.trigger( "focus" );
252		}
253	},
254
255	// Alt+page up/down moves focus to the previous/next tab (and activates)
256	_handlePageNav: function( event ) {
257		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
258			this._activate( this._focusNextTab( this.options.active - 1, false ) );
259			return true;
260		}
261		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
262			this._activate( this._focusNextTab( this.options.active + 1, true ) );
263			return true;
264		}
265	},
266
267	_findNextTab: function( index, goingForward ) {
268		var lastTabIndex = this.tabs.length - 1;
269
270		function constrain() {
271			if ( index > lastTabIndex ) {
272				index = 0;
273			}
274			if ( index < 0 ) {
275				index = lastTabIndex;
276			}
277			return index;
278		}
279
280		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
281			index = goingForward ? index + 1 : index - 1;
282		}
283
284		return index;
285	},
286
287	_focusNextTab: function( index, goingForward ) {
288		index = this._findNextTab( index, goingForward );
289		this.tabs.eq( index ).trigger( "focus" );
290		return index;
291	},
292
293	_setOption: function( key, value ) {
294		if ( key === "active" ) {
295
296			// _activate() will handle invalid values and update this.options
297			this._activate( value );
298			return;
299		}
300
301		this._super( key, value );
302
303		if ( key === "collapsible" ) {
304			this._toggleClass( "ui-tabs-collapsible", null, value );
305
306			// Setting collapsible: false while collapsed; open first panel
307			if ( !value && this.options.active === false ) {
308				this._activate( 0 );
309			}
310		}
311
312		if ( key === "event" ) {
313			this._setupEvents( value );
314		}
315
316		if ( key === "heightStyle" ) {
317			this._setupHeightStyle( value );
318		}
319	},
320
321	refresh: function() {
322		var options = this.options,
323			lis = this.tablist.children( ":has(a[href])" );
324
325		// Get disabled tabs from class attribute from HTML
326		// this will get converted to a boolean if needed in _refresh()
327		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
328			return lis.index( tab );
329		} );
330
331		this._processTabs();
332
333		// Was collapsed or no tabs
334		if ( options.active === false || !this.anchors.length ) {
335			options.active = false;
336			this.active = $();
337
338		// was active, but active tab is gone
339		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
340
341			// all remaining tabs are disabled
342			if ( this.tabs.length === options.disabled.length ) {
343				options.active = false;
344				this.active = $();
345
346			// activate previous tab
347			} else {
348				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
349			}
350
351		// was active, active tab still exists
352		} else {
353
354			// make sure active index is correct
355			options.active = this.tabs.index( this.active );
356		}
357
358		this._refresh();
359	},
360
361	_refresh: function() {
362		this._setOptionDisabled( this.options.disabled );
363		this._setupEvents( this.options.event );
364		this._setupHeightStyle( this.options.heightStyle );
365
366		this.tabs.not( this.active ).attr( {
367			"aria-selected": "false",
368			"aria-expanded": "false",
369			tabIndex: -1
370		} );
371		this.panels.not( this._getPanelForTab( this.active ) )
372			.hide()
373			.attr( {
374				"aria-hidden": "true"
375			} );
376
377		// Make sure one tab is in the tab order
378		if ( !this.active.length ) {
379			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
380		} else {
381			this.active
382				.attr( {
383					"aria-selected": "true",
384					"aria-expanded": "true",
385					tabIndex: 0
386				} );
387			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
388			this._getPanelForTab( this.active )
389				.show()
390				.attr( {
391					"aria-hidden": "false"
392				} );
393		}
394	},
395
396	_processTabs: function() {
397		var that = this,
398			prevTabs = this.tabs,
399			prevAnchors = this.anchors,
400			prevPanels = this.panels;
401
402		this.tablist = this._getList().attr( "role", "tablist" );
403		this._addClass( this.tablist, "ui-tabs-nav",
404			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
405
406		// Prevent users from focusing disabled tabs via click
407		this.tablist
408			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
409				if ( $( this ).is( ".ui-state-disabled" ) ) {
410					event.preventDefault();
411				}
412			} );
413
414		this.tabs = this.tablist.find( "> li:has(a[href])" )
415			.attr( {
416				role: "tab",
417				tabIndex: -1
418			} );
419		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
420
421		this.anchors = this.tabs.map( function() {
422			return $( "a", this )[ 0 ];
423		} )
424			.attr( {
425				tabIndex: -1
426			} );
427		this._addClass( this.anchors, "ui-tabs-anchor" );
428
429		this.panels = $();
430
431		this.anchors.each( function( i, anchor ) {
432			var selector, panel, panelId,
433				anchorId = $( anchor ).uniqueId().attr( "id" ),
434				tab = $( anchor ).closest( "li" ),
435				originalAriaControls = tab.attr( "aria-controls" );
436
437			// Inline tab
438			if ( that._isLocal( anchor ) ) {
439
440				// The "scrolling to a fragment" section of the HTML spec:
441				// https://html.spec.whatwg.org/#scrolling-to-a-fragment
442				// uses a concept of document's indicated part:
443				// https://html.spec.whatwg.org/#the-indicated-part-of-the-document
444				// Slightly below there's an algorithm to compute the indicated
445				// part:
446				// https://html.spec.whatwg.org/#the-indicated-part-of-the-document
447				// First, the algorithm tries the hash as-is, without decoding.
448				// Then, if one is not found, the same is attempted with a decoded
449				// hash. Replicate this logic.
450				selector = anchor.hash;
451				panelId = selector.substring( 1 );
452				panel = that.element.find( "#" + CSS.escape( panelId ) );
453				if ( !panel.length ) {
454					panelId = decodeURIComponent( panelId );
455					panel = that.element.find( "#" + CSS.escape( panelId ) );
456				}
457
458			// remote tab
459			} else {
460
461				// If the tab doesn't already have aria-controls,
462				// generate an id by using a throw-away element
463				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
464				selector = "#" + panelId;
465				panel = that.element.find( selector );
466				if ( !panel.length ) {
467					panel = that._createPanel( panelId );
468					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
469				}
470				panel.attr( "aria-live", "polite" );
471			}
472
473			if ( panel.length ) {
474				that.panels = that.panels.add( panel );
475			}
476			if ( originalAriaControls ) {
477				tab.data( "ui-tabs-aria-controls", originalAriaControls );
478			}
479			tab.attr( {
480				"aria-controls": panelId,
481				"aria-labelledby": anchorId
482			} );
483			panel.attr( "aria-labelledby", anchorId );
484		} );
485
486		this.panels.attr( "role", "tabpanel" );
487		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
488
489		// Avoid memory leaks (#10056)
490		if ( prevTabs ) {
491			this._off( prevTabs.not( this.tabs ) );
492			this._off( prevAnchors.not( this.anchors ) );
493			this._off( prevPanels.not( this.panels ) );
494		}
495	},
496
497	// Allow overriding how to find the list for rare usage scenarios (#7715)
498	_getList: function() {
499		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
500	},
501
502	_createPanel: function( id ) {
503		return $( "<div>" )
504			.attr( "id", id )
505			.data( "ui-tabs-destroy", true );
506	},
507
508	_setOptionDisabled: function( disabled ) {
509		var currentItem, li, i;
510
511		if ( Array.isArray( disabled ) ) {
512			if ( !disabled.length ) {
513				disabled = false;
514			} else if ( disabled.length === this.anchors.length ) {
515				disabled = true;
516			}
517		}
518
519		// Disable tabs
520		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
521			currentItem = $( li );
522			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
523				currentItem.attr( "aria-disabled", "true" );
524				this._addClass( currentItem, null, "ui-state-disabled" );
525			} else {
526				currentItem.removeAttr( "aria-disabled" );
527				this._removeClass( currentItem, null, "ui-state-disabled" );
528			}
529		}
530
531		this.options.disabled = disabled;
532
533		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
534			disabled === true );
535	},
536
537	_setupEvents: function( event ) {
538		var events = {};
539		if ( event ) {
540			$.each( event.split( " " ), function( index, eventName ) {
541				events[ eventName ] = "_eventHandler";
542			} );
543		}
544
545		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
546
547		// Always prevent the default action, even when disabled
548		this._on( true, this.anchors, {
549			click: function( event ) {
550				event.preventDefault();
551			}
552		} );
553		this._on( this.anchors, events );
554		this._on( this.tabs, { keydown: "_tabKeydown" } );
555		this._on( this.panels, { keydown: "_panelKeydown" } );
556
557		this._focusable( this.tabs );
558		this._hoverable( this.tabs );
559	},
560
561	_setupHeightStyle: function( heightStyle ) {
562		var maxHeight,
563			parent = this.element.parent();
564
565		if ( heightStyle === "fill" ) {
566			maxHeight = parent.height();
567			maxHeight -= this.element.outerHeight() - this.element.height();
568
569			this.element.siblings( ":visible" ).each( function() {
570				var elem = $( this ),
571					position = elem.css( "position" );
572
573				if ( position === "absolute" || position === "fixed" ) {
574					return;
575				}
576				maxHeight -= elem.outerHeight( true );
577			} );
578
579			this.element.children().not( this.panels ).each( function() {
580				maxHeight -= $( this ).outerHeight( true );
581			} );
582
583			this.panels.each( function() {
584				$( this ).height( Math.max( 0, maxHeight -
585					$( this ).innerHeight() + $( this ).height() ) );
586			} )
587				.css( "overflow", "auto" );
588		} else if ( heightStyle === "auto" ) {
589			maxHeight = 0;
590			this.panels.each( function() {
591				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
592			} ).height( maxHeight );
593		}
594	},
595
596	_eventHandler: function( event ) {
597		var options = this.options,
598			active = this.active,
599			anchor = $( event.currentTarget ),
600			tab = anchor.closest( "li" ),
601			clickedIsActive = tab[ 0 ] === active[ 0 ],
602			collapsing = clickedIsActive && options.collapsible,
603			toShow = collapsing ? $() : this._getPanelForTab( tab ),
604			toHide = !active.length ? $() : this._getPanelForTab( active ),
605			eventData = {
606				oldTab: active,
607				oldPanel: toHide,
608				newTab: collapsing ? $() : tab,
609				newPanel: toShow
610			};
611
612		event.preventDefault();
613
614		if ( tab.hasClass( "ui-state-disabled" ) ||
615
616				// tab is already loading
617				tab.hasClass( "ui-tabs-loading" ) ||
618
619				// can't switch durning an animation
620				this.running ||
621
622				// click on active header, but not collapsible
623				( clickedIsActive && !options.collapsible ) ||
624
625				// allow canceling activation
626				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
627			return;
628		}
629
630		options.active = collapsing ? false : this.tabs.index( tab );
631
632		this.active = clickedIsActive ? $() : tab;
633		if ( this.xhr ) {
634			this.xhr.abort();
635		}
636
637		if ( !toHide.length && !toShow.length ) {
638			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
639		}
640
641		if ( toShow.length ) {
642			this.load( this.tabs.index( tab ), event );
643		}
644		this._toggle( event, eventData );
645	},
646
647	// Handles show/hide for selecting tabs
648	_toggle: function( event, eventData ) {
649		var that = this,
650			toShow = eventData.newPanel,
651			toHide = eventData.oldPanel;
652
653		this.running = true;
654
655		function complete() {
656			that.running = false;
657			that._trigger( "activate", event, eventData );
658		}
659
660		function show() {
661			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
662
663			if ( toShow.length && that.options.show ) {
664				that._show( toShow, that.options.show, complete );
665			} else {
666				toShow.show();
667				complete();
668			}
669		}
670
671		// Start out by hiding, then showing, then completing
672		if ( toHide.length && this.options.hide ) {
673			this._hide( toHide, this.options.hide, function() {
674				that._removeClass( eventData.oldTab.closest( "li" ),
675					"ui-tabs-active", "ui-state-active" );
676				show();
677			} );
678		} else {
679			this._removeClass( eventData.oldTab.closest( "li" ),
680				"ui-tabs-active", "ui-state-active" );
681			toHide.hide();
682			show();
683		}
684
685		toHide.attr( "aria-hidden", "true" );
686		eventData.oldTab.attr( {
687			"aria-selected": "false",
688			"aria-expanded": "false"
689		} );
690
691		// If we're switching tabs, remove the old tab from the tab order.
692		// If we're opening from collapsed state, remove the previous tab from the tab order.
693		// If we're collapsing, then keep the collapsing tab in the tab order.
694		if ( toShow.length && toHide.length ) {
695			eventData.oldTab.attr( "tabIndex", -1 );
696		} else if ( toShow.length ) {
697			this.tabs.filter( function() {
698				return $( this ).attr( "tabIndex" ) === 0;
699			} )
700				.attr( "tabIndex", -1 );
701		}
702
703		toShow.attr( "aria-hidden", "false" );
704		eventData.newTab.attr( {
705			"aria-selected": "true",
706			"aria-expanded": "true",
707			tabIndex: 0
708		} );
709	},
710
711	_activate: function( index ) {
712		var anchor,
713			active = this._findActive( index );
714
715		// Trying to activate the already active panel
716		if ( active[ 0 ] === this.active[ 0 ] ) {
717			return;
718		}
719
720		// Trying to collapse, simulate a click on the current active header
721		if ( !active.length ) {
722			active = this.active;
723		}
724
725		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
726		this._eventHandler( {
727			target: anchor,
728			currentTarget: anchor,
729			preventDefault: $.noop
730		} );
731	},
732
733	_findActive: function( index ) {
734		return index === false ? $() : this.tabs.eq( index );
735	},
736
737	_getIndex: function( index ) {
738
739		// meta-function to give users option to provide a href string instead of a numerical index.
740		if ( typeof index === "string" ) {
741			index = this.anchors.index( this.anchors.filter( "[href$='" +
742				CSS.escape( index ) + "']" ) );
743		}
744
745		return index;
746	},
747
748	_destroy: function() {
749		if ( this.xhr ) {
750			this.xhr.abort();
751		}
752
753		this.tablist
754			.removeAttr( "role" )
755			.off( this.eventNamespace );
756
757		this.anchors
758			.removeAttr( "role tabIndex" )
759			.removeUniqueId();
760
761		this.tabs.add( this.panels ).each( function() {
762			if ( $.data( this, "ui-tabs-destroy" ) ) {
763				$( this ).remove();
764			} else {
765				$( this ).removeAttr( "role tabIndex " +
766					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
767			}
768		} );
769
770		this.tabs.each( function() {
771			var li = $( this ),
772				prev = li.data( "ui-tabs-aria-controls" );
773			if ( prev ) {
774				li
775					.attr( "aria-controls", prev )
776					.removeData( "ui-tabs-aria-controls" );
777			} else {
778				li.removeAttr( "aria-controls" );
779			}
780		} );
781
782		this.panels.show();
783
784		if ( this.options.heightStyle !== "content" ) {
785			this.panels.css( "height", "" );
786		}
787	},
788
789	enable: function( index ) {
790		var disabled = this.options.disabled;
791		if ( disabled === false ) {
792			return;
793		}
794
795		if ( index === undefined ) {
796			disabled = false;
797		} else {
798			index = this._getIndex( index );
799			if ( Array.isArray( disabled ) ) {
800				disabled = $.map( disabled, function( num ) {
801					return num !== index ? num : null;
802				} );
803			} else {
804				disabled = $.map( this.tabs, function( li, num ) {
805					return num !== index ? num : null;
806				} );
807			}
808		}
809		this._setOptionDisabled( disabled );
810	},
811
812	disable: function( index ) {
813		var disabled = this.options.disabled;
814		if ( disabled === true ) {
815			return;
816		}
817
818		if ( index === undefined ) {
819			disabled = true;
820		} else {
821			index = this._getIndex( index );
822			if ( $.inArray( index, disabled ) !== -1 ) {
823				return;
824			}
825			if ( Array.isArray( disabled ) ) {
826				disabled = $.merge( [ index ], disabled ).sort();
827			} else {
828				disabled = [ index ];
829			}
830		}
831		this._setOptionDisabled( disabled );
832	},
833
834	load: function( index, event ) {
835		index = this._getIndex( index );
836		var that = this,
837			tab = this.tabs.eq( index ),
838			anchor = tab.find( ".ui-tabs-anchor" ),
839			panel = this._getPanelForTab( tab ),
840			eventData = {
841				tab: tab,
842				panel: panel
843			},
844			complete = function( jqXHR, status ) {
845				if ( status === "abort" ) {
846					that.panels.stop( false, true );
847				}
848
849				that._removeClass( tab, "ui-tabs-loading" );
850				panel.removeAttr( "aria-busy" );
851
852				if ( jqXHR === that.xhr ) {
853					delete that.xhr;
854				}
855			};
856
857		// Not remote
858		if ( this._isLocal( anchor[ 0 ] ) ) {
859			return;
860		}
861
862		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
863
864		if ( this.xhr.statusText !== "canceled" ) {
865			this._addClass( tab, "ui-tabs-loading" );
866			panel.attr( "aria-busy", "true" );
867
868			this.xhr
869				.done( function( response, status, jqXHR ) {
870					panel.html( response );
871					that._trigger( "load", event, eventData );
872
873					complete( jqXHR, status );
874				} )
875				.fail( function( jqXHR, status ) {
876					complete( jqXHR, status );
877				} );
878		}
879	},
880
881	_ajaxSettings: function( anchor, event, eventData ) {
882		var that = this;
883		return {
884			url: anchor.attr( "href" ),
885			beforeSend: function( jqXHR, settings ) {
886				return that._trigger( "beforeLoad", event,
887					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
888			}
889		};
890	},
891
892	_getPanelForTab: function( tab ) {
893		var id = $( tab ).attr( "aria-controls" );
894		return this.element.find( "#" + CSS.escape( id ) );
895	}
896} );
897
898// DEPRECATED
899// TODO: Switch return back to widget declaration at top of file when this is removed
900if ( $.uiBackCompat === true ) {
901
902	// Backcompat for ui-tab class (now ui-tabs-tab)
903	$.widget( "ui.tabs", $.ui.tabs, {
904		_processTabs: function() {
905			this._superApply( arguments );
906			this._addClass( this.tabs, "ui-tab" );
907		}
908	} );
909}
910
911return $.ui.tabs;
912
913} );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.