Mercurial > hg > STI-GWT
comparison war/scripts/jQuery/ui/jquery.ui.tabs.js @ 3:cf06b77a8bbd
Committed branch of the e4D repos sti-gwt branch 16384.
git-svn-id: http://dev.dariah.eu/svn/repos/eu.dariah.de/ap1/sti-gwt-dariah-geobrowser@36 f2b5be40-def6-11e0-8a09-b3c1cc336c6b
author | StefanFunk <StefanFunk@f2b5be40-def6-11e0-8a09-b3c1cc336c6b> |
---|---|
date | Tue, 17 Jul 2012 13:34:40 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:2897af43ccc6 | 3:cf06b77a8bbd |
---|---|
1 /* | |
2 * jQuery UI Tabs 1.8.14 | |
3 * | |
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) | |
5 * Dual licensed under the MIT or GPL Version 2 licenses. | |
6 * http://jquery.org/license | |
7 * | |
8 * http://docs.jquery.com/UI/Tabs | |
9 * | |
10 * Depends: | |
11 * jquery.ui.core.js | |
12 * jquery.ui.widget.js | |
13 */ | |
14 (function( $, undefined ) { | |
15 | |
16 var tabId = 0, | |
17 listId = 0; | |
18 | |
19 function getNextTabId() { | |
20 return ++tabId; | |
21 } | |
22 | |
23 function getNextListId() { | |
24 return ++listId; | |
25 } | |
26 | |
27 $.widget( "ui.tabs", { | |
28 options: { | |
29 add: null, | |
30 ajaxOptions: null, | |
31 cache: false, | |
32 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } | |
33 collapsible: false, | |
34 disable: null, | |
35 disabled: [], | |
36 enable: null, | |
37 event: "click", | |
38 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } | |
39 idPrefix: "ui-tabs-", | |
40 load: null, | |
41 panelTemplate: "<div></div>", | |
42 remove: null, | |
43 select: null, | |
44 show: null, | |
45 spinner: "<em>Loading…</em>", | |
46 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>" | |
47 }, | |
48 | |
49 _create: function() { | |
50 this._tabify( true ); | |
51 }, | |
52 | |
53 _setOption: function( key, value ) { | |
54 if ( key == "selected" ) { | |
55 if (this.options.collapsible && value == this.options.selected ) { | |
56 return; | |
57 } | |
58 this.select( value ); | |
59 } else { | |
60 this.options[ key ] = value; | |
61 this._tabify(); | |
62 } | |
63 }, | |
64 | |
65 _tabId: function( a ) { | |
66 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) || | |
67 this.options.idPrefix + getNextTabId(); | |
68 }, | |
69 | |
70 _sanitizeSelector: function( hash ) { | |
71 // we need this because an id may contain a ":" | |
72 return hash.replace( /:/g, "\\:" ); | |
73 }, | |
74 | |
75 _cookie: function() { | |
76 var cookie = this.cookie || | |
77 ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); | |
78 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); | |
79 }, | |
80 | |
81 _ui: function( tab, panel ) { | |
82 return { | |
83 tab: tab, | |
84 panel: panel, | |
85 index: this.anchors.index( tab ) | |
86 }; | |
87 }, | |
88 | |
89 _cleanup: function() { | |
90 // restore all former loading tabs labels | |
91 this.lis.filter( ".ui-state-processing" ) | |
92 .removeClass( "ui-state-processing" ) | |
93 .find( "span:data(label.tabs)" ) | |
94 .each(function() { | |
95 var el = $( this ); | |
96 el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" ); | |
97 }); | |
98 }, | |
99 | |
100 _tabify: function( init ) { | |
101 var self = this, | |
102 o = this.options, | |
103 fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash | |
104 | |
105 this.list = this.element.find( "ol,ul" ).eq( 0 ); | |
106 this.lis = $( " > li:has(a[href])", this.list ); | |
107 this.anchors = this.lis.map(function() { | |
108 return $( "a", this )[ 0 ]; | |
109 }); | |
110 this.panels = $( [] ); | |
111 | |
112 this.anchors.each(function( i, a ) { | |
113 var href = $( a ).attr( "href" ); | |
114 // For dynamically created HTML that contains a hash as href IE < 8 expands | |
115 // such href to the full page url with hash and then misinterprets tab as ajax. | |
116 // Same consideration applies for an added tab with a fragment identifier | |
117 // since a[href=#fragment-identifier] does unexpectedly not match. | |
118 // Thus normalize href attribute... | |
119 var hrefBase = href.split( "#" )[ 0 ], | |
120 baseEl; | |
121 if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || | |
122 ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { | |
123 href = a.hash; | |
124 a.href = href; | |
125 } | |
126 | |
127 // inline tab | |
128 if ( fragmentId.test( href ) ) { | |
129 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) ); | |
130 // remote tab | |
131 // prevent loading the page itself if href is just "#" | |
132 } else if ( href && href !== "#" ) { | |
133 // required for restore on destroy | |
134 $.data( a, "href.tabs", href ); | |
135 | |
136 // TODO until #3808 is fixed strip fragment identifier from url | |
137 // (IE fails to load from such url) | |
138 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) ); | |
139 | |
140 var id = self._tabId( a ); | |
141 a.href = "#" + id; | |
142 var $panel = self.element.find( "#" + id ); | |
143 if ( !$panel.length ) { | |
144 $panel = $( o.panelTemplate ) | |
145 .attr( "id", id ) | |
146 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) | |
147 .insertAfter( self.panels[ i - 1 ] || self.list ); | |
148 $panel.data( "destroy.tabs", true ); | |
149 } | |
150 self.panels = self.panels.add( $panel ); | |
151 // invalid tab href | |
152 } else { | |
153 o.disabled.push( i ); | |
154 } | |
155 }); | |
156 | |
157 // initialization from scratch | |
158 if ( init ) { | |
159 // attach necessary classes for styling | |
160 this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ); | |
161 this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); | |
162 this.lis.addClass( "ui-state-default ui-corner-top" ); | |
163 this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); | |
164 | |
165 // Selected tab | |
166 // use "selected" option or try to retrieve: | |
167 // 1. from fragment identifier in url | |
168 // 2. from cookie | |
169 // 3. from selected class attribute on <li> | |
170 if ( o.selected === undefined ) { | |
171 if ( location.hash ) { | |
172 this.anchors.each(function( i, a ) { | |
173 if ( a.hash == location.hash ) { | |
174 o.selected = i; | |
175 return false; | |
176 } | |
177 }); | |
178 } | |
179 if ( typeof o.selected !== "number" && o.cookie ) { | |
180 o.selected = parseInt( self._cookie(), 10 ); | |
181 } | |
182 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) { | |
183 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); | |
184 } | |
185 o.selected = o.selected || ( this.lis.length ? 0 : -1 ); | |
186 } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release | |
187 o.selected = -1; | |
188 } | |
189 | |
190 // sanity check - default to first tab... | |
191 o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 ) | |
192 ? o.selected | |
193 : 0; | |
194 | |
195 // Take disabling tabs via class attribute from HTML | |
196 // into account and update option properly. | |
197 // A selected tab cannot become disabled. | |
198 o.disabled = $.unique( o.disabled.concat( | |
199 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) { | |
200 return self.lis.index( n ); | |
201 }) | |
202 ) ).sort(); | |
203 | |
204 if ( $.inArray( o.selected, o.disabled ) != -1 ) { | |
205 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 ); | |
206 } | |
207 | |
208 // highlight selected tab | |
209 this.panels.addClass( "ui-tabs-hide" ); | |
210 this.lis.removeClass( "ui-tabs-selected ui-state-active" ); | |
211 // check for length avoids error when initializing empty list | |
212 if ( o.selected >= 0 && this.anchors.length ) { | |
213 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" ); | |
214 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" ); | |
215 | |
216 // seems to be expected behavior that the show callback is fired | |
217 self.element.queue( "tabs", function() { | |
218 self._trigger( "show", null, | |
219 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) ); | |
220 }); | |
221 | |
222 this.load( o.selected ); | |
223 } | |
224 | |
225 // clean up to avoid memory leaks in certain versions of IE 6 | |
226 // TODO: namespace this event | |
227 $( window ).bind( "unload", function() { | |
228 self.lis.add( self.anchors ).unbind( ".tabs" ); | |
229 self.lis = self.anchors = self.panels = null; | |
230 }); | |
231 // update selected after add/remove | |
232 } else { | |
233 o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); | |
234 } | |
235 | |
236 // update collapsible | |
237 // TODO: use .toggleClass() | |
238 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" ); | |
239 | |
240 // set or update cookie after init and add/remove respectively | |
241 if ( o.cookie ) { | |
242 this._cookie( o.selected, o.cookie ); | |
243 } | |
244 | |
245 // disable tabs | |
246 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { | |
247 $( li )[ $.inArray( i, o.disabled ) != -1 && | |
248 // TODO: use .toggleClass() | |
249 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" ); | |
250 } | |
251 | |
252 // reset cache if switching from cached to not cached | |
253 if ( o.cache === false ) { | |
254 this.anchors.removeData( "cache.tabs" ); | |
255 } | |
256 | |
257 // remove all handlers before, tabify may run on existing tabs after add or option change | |
258 this.lis.add( this.anchors ).unbind( ".tabs" ); | |
259 | |
260 if ( o.event !== "mouseover" ) { | |
261 var addState = function( state, el ) { | |
262 if ( el.is( ":not(.ui-state-disabled)" ) ) { | |
263 el.addClass( "ui-state-" + state ); | |
264 } | |
265 }; | |
266 var removeState = function( state, el ) { | |
267 el.removeClass( "ui-state-" + state ); | |
268 }; | |
269 this.lis.bind( "mouseover.tabs" , function() { | |
270 addState( "hover", $( this ) ); | |
271 }); | |
272 this.lis.bind( "mouseout.tabs", function() { | |
273 removeState( "hover", $( this ) ); | |
274 }); | |
275 this.anchors.bind( "focus.tabs", function() { | |
276 addState( "focus", $( this ).closest( "li" ) ); | |
277 }); | |
278 this.anchors.bind( "blur.tabs", function() { | |
279 removeState( "focus", $( this ).closest( "li" ) ); | |
280 }); | |
281 } | |
282 | |
283 // set up animations | |
284 var hideFx, showFx; | |
285 if ( o.fx ) { | |
286 if ( $.isArray( o.fx ) ) { | |
287 hideFx = o.fx[ 0 ]; | |
288 showFx = o.fx[ 1 ]; | |
289 } else { | |
290 hideFx = showFx = o.fx; | |
291 } | |
292 } | |
293 | |
294 // Reset certain styles left over from animation | |
295 // and prevent IE's ClearType bug... | |
296 function resetStyle( $el, fx ) { | |
297 $el.css( "display", "" ); | |
298 if ( !$.support.opacity && fx.opacity ) { | |
299 $el[ 0 ].style.removeAttribute( "filter" ); | |
300 } | |
301 } | |
302 | |
303 // Show a tab... | |
304 var showTab = showFx | |
305 ? function( clicked, $show ) { | |
306 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); | |
307 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way | |
308 .animate( showFx, showFx.duration || "normal", function() { | |
309 resetStyle( $show, showFx ); | |
310 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); | |
311 }); | |
312 } | |
313 : function( clicked, $show ) { | |
314 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); | |
315 $show.removeClass( "ui-tabs-hide" ); | |
316 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); | |
317 }; | |
318 | |
319 // Hide a tab, $show is optional... | |
320 var hideTab = hideFx | |
321 ? function( clicked, $hide ) { | |
322 $hide.animate( hideFx, hideFx.duration || "normal", function() { | |
323 self.lis.removeClass( "ui-tabs-selected ui-state-active" ); | |
324 $hide.addClass( "ui-tabs-hide" ); | |
325 resetStyle( $hide, hideFx ); | |
326 self.element.dequeue( "tabs" ); | |
327 }); | |
328 } | |
329 : function( clicked, $hide, $show ) { | |
330 self.lis.removeClass( "ui-tabs-selected ui-state-active" ); | |
331 $hide.addClass( "ui-tabs-hide" ); | |
332 self.element.dequeue( "tabs" ); | |
333 }; | |
334 | |
335 // attach tab event handler, unbind to avoid duplicates from former tabifying... | |
336 this.anchors.bind( o.event + ".tabs", function() { | |
337 var el = this, | |
338 $li = $(el).closest( "li" ), | |
339 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), | |
340 $show = self.element.find( self._sanitizeSelector( el.hash ) ); | |
341 | |
342 // If tab is already selected and not collapsible or tab disabled or | |
343 // or is already loading or click callback returns false stop here. | |
344 // Check if click handler returns false last so that it is not executed | |
345 // for a disabled or loading tab! | |
346 if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) || | |
347 $li.hasClass( "ui-state-disabled" ) || | |
348 $li.hasClass( "ui-state-processing" ) || | |
349 self.panels.filter( ":animated" ).length || | |
350 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) { | |
351 this.blur(); | |
352 return false; | |
353 } | |
354 | |
355 o.selected = self.anchors.index( this ); | |
356 | |
357 self.abort(); | |
358 | |
359 // if tab may be closed | |
360 if ( o.collapsible ) { | |
361 if ( $li.hasClass( "ui-tabs-selected" ) ) { | |
362 o.selected = -1; | |
363 | |
364 if ( o.cookie ) { | |
365 self._cookie( o.selected, o.cookie ); | |
366 } | |
367 | |
368 self.element.queue( "tabs", function() { | |
369 hideTab( el, $hide ); | |
370 }).dequeue( "tabs" ); | |
371 | |
372 this.blur(); | |
373 return false; | |
374 } else if ( !$hide.length ) { | |
375 if ( o.cookie ) { | |
376 self._cookie( o.selected, o.cookie ); | |
377 } | |
378 | |
379 self.element.queue( "tabs", function() { | |
380 showTab( el, $show ); | |
381 }); | |
382 | |
383 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 | |
384 self.load( self.anchors.index( this ) ); | |
385 | |
386 this.blur(); | |
387 return false; | |
388 } | |
389 } | |
390 | |
391 if ( o.cookie ) { | |
392 self._cookie( o.selected, o.cookie ); | |
393 } | |
394 | |
395 // show new tab | |
396 if ( $show.length ) { | |
397 if ( $hide.length ) { | |
398 self.element.queue( "tabs", function() { | |
399 hideTab( el, $hide ); | |
400 }); | |
401 } | |
402 self.element.queue( "tabs", function() { | |
403 showTab( el, $show ); | |
404 }); | |
405 | |
406 self.load( self.anchors.index( this ) ); | |
407 } else { | |
408 throw "jQuery UI Tabs: Mismatching fragment identifier."; | |
409 } | |
410 | |
411 // Prevent IE from keeping other link focussed when using the back button | |
412 // and remove dotted border from clicked link. This is controlled via CSS | |
413 // in modern browsers; blur() removes focus from address bar in Firefox | |
414 // which can become a usability and annoying problem with tabs('rotate'). | |
415 if ( $.browser.msie ) { | |
416 this.blur(); | |
417 } | |
418 }); | |
419 | |
420 // disable click in any case | |
421 this.anchors.bind( "click.tabs", function(){ | |
422 return false; | |
423 }); | |
424 }, | |
425 | |
426 _getIndex: function( index ) { | |
427 // meta-function to give users option to provide a href string instead of a numerical index. | |
428 // also sanitizes numerical indexes to valid values. | |
429 if ( typeof index == "string" ) { | |
430 index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) ); | |
431 } | |
432 | |
433 return index; | |
434 }, | |
435 | |
436 destroy: function() { | |
437 var o = this.options; | |
438 | |
439 this.abort(); | |
440 | |
441 this.element | |
442 .unbind( ".tabs" ) | |
443 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ) | |
444 .removeData( "tabs" ); | |
445 | |
446 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); | |
447 | |
448 this.anchors.each(function() { | |
449 var href = $.data( this, "href.tabs" ); | |
450 if ( href ) { | |
451 this.href = href; | |
452 } | |
453 var $this = $( this ).unbind( ".tabs" ); | |
454 $.each( [ "href", "load", "cache" ], function( i, prefix ) { | |
455 $this.removeData( prefix + ".tabs" ); | |
456 }); | |
457 }); | |
458 | |
459 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() { | |
460 if ( $.data( this, "destroy.tabs" ) ) { | |
461 $( this ).remove(); | |
462 } else { | |
463 $( this ).removeClass([ | |
464 "ui-state-default", | |
465 "ui-corner-top", | |
466 "ui-tabs-selected", | |
467 "ui-state-active", | |
468 "ui-state-hover", | |
469 "ui-state-focus", | |
470 "ui-state-disabled", | |
471 "ui-tabs-panel", | |
472 "ui-widget-content", | |
473 "ui-corner-bottom", | |
474 "ui-tabs-hide" | |
475 ].join( " " ) ); | |
476 } | |
477 }); | |
478 | |
479 if ( o.cookie ) { | |
480 this._cookie( null, o.cookie ); | |
481 } | |
482 | |
483 return this; | |
484 }, | |
485 | |
486 add: function( url, label, index ) { | |
487 if ( index === undefined ) { | |
488 index = this.anchors.length; | |
489 } | |
490 | |
491 var self = this, | |
492 o = this.options, | |
493 $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), | |
494 id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); | |
495 | |
496 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); | |
497 | |
498 // try to find an existing element before creating a new one | |
499 var $panel = self.element.find( "#" + id ); | |
500 if ( !$panel.length ) { | |
501 $panel = $( o.panelTemplate ) | |
502 .attr( "id", id ) | |
503 .data( "destroy.tabs", true ); | |
504 } | |
505 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" ); | |
506 | |
507 if ( index >= this.lis.length ) { | |
508 $li.appendTo( this.list ); | |
509 $panel.appendTo( this.list[ 0 ].parentNode ); | |
510 } else { | |
511 $li.insertBefore( this.lis[ index ] ); | |
512 $panel.insertBefore( this.panels[ index ] ); | |
513 } | |
514 | |
515 o.disabled = $.map( o.disabled, function( n, i ) { | |
516 return n >= index ? ++n : n; | |
517 }); | |
518 | |
519 this._tabify(); | |
520 | |
521 if ( this.anchors.length == 1 ) { | |
522 o.selected = 0; | |
523 $li.addClass( "ui-tabs-selected ui-state-active" ); | |
524 $panel.removeClass( "ui-tabs-hide" ); | |
525 this.element.queue( "tabs", function() { | |
526 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); | |
527 }); | |
528 | |
529 this.load( 0 ); | |
530 } | |
531 | |
532 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); | |
533 return this; | |
534 }, | |
535 | |
536 remove: function( index ) { | |
537 index = this._getIndex( index ); | |
538 var o = this.options, | |
539 $li = this.lis.eq( index ).remove(), | |
540 $panel = this.panels.eq( index ).remove(); | |
541 | |
542 // If selected tab was removed focus tab to the right or | |
543 // in case the last tab was removed the tab to the left. | |
544 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { | |
545 this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); | |
546 } | |
547 | |
548 o.disabled = $.map( | |
549 $.grep( o.disabled, function(n, i) { | |
550 return n != index; | |
551 }), | |
552 function( n, i ) { | |
553 return n >= index ? --n : n; | |
554 }); | |
555 | |
556 this._tabify(); | |
557 | |
558 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); | |
559 return this; | |
560 }, | |
561 | |
562 enable: function( index ) { | |
563 index = this._getIndex( index ); | |
564 var o = this.options; | |
565 if ( $.inArray( index, o.disabled ) == -1 ) { | |
566 return; | |
567 } | |
568 | |
569 this.lis.eq( index ).removeClass( "ui-state-disabled" ); | |
570 o.disabled = $.grep( o.disabled, function( n, i ) { | |
571 return n != index; | |
572 }); | |
573 | |
574 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); | |
575 return this; | |
576 }, | |
577 | |
578 disable: function( index ) { | |
579 index = this._getIndex( index ); | |
580 var self = this, o = this.options; | |
581 // cannot disable already selected tab | |
582 if ( index != o.selected ) { | |
583 this.lis.eq( index ).addClass( "ui-state-disabled" ); | |
584 | |
585 o.disabled.push( index ); | |
586 o.disabled.sort(); | |
587 | |
588 this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); | |
589 } | |
590 | |
591 return this; | |
592 }, | |
593 | |
594 select: function( index ) { | |
595 index = this._getIndex( index ); | |
596 if ( index == -1 ) { | |
597 if ( this.options.collapsible && this.options.selected != -1 ) { | |
598 index = this.options.selected; | |
599 } else { | |
600 return this; | |
601 } | |
602 } | |
603 this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); | |
604 return this; | |
605 }, | |
606 | |
607 load: function( index ) { | |
608 index = this._getIndex( index ); | |
609 var self = this, | |
610 o = this.options, | |
611 a = this.anchors.eq( index )[ 0 ], | |
612 url = $.data( a, "load.tabs" ); | |
613 | |
614 this.abort(); | |
615 | |
616 // not remote or from cache | |
617 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) { | |
618 this.element.dequeue( "tabs" ); | |
619 return; | |
620 } | |
621 | |
622 // load remote from here on | |
623 this.lis.eq( index ).addClass( "ui-state-processing" ); | |
624 | |
625 if ( o.spinner ) { | |
626 var span = $( "span", a ); | |
627 span.data( "label.tabs", span.html() ).html( o.spinner ); | |
628 } | |
629 | |
630 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, { | |
631 url: url, | |
632 success: function( r, s ) { | |
633 self.element.find( self._sanitizeSelector( a.hash ) ).html( r ); | |
634 | |
635 // take care of tab labels | |
636 self._cleanup(); | |
637 | |
638 if ( o.cache ) { | |
639 $.data( a, "cache.tabs", true ); | |
640 } | |
641 | |
642 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); | |
643 try { | |
644 o.ajaxOptions.success( r, s ); | |
645 } | |
646 catch ( e ) {} | |
647 }, | |
648 error: function( xhr, s, e ) { | |
649 // take care of tab labels | |
650 self._cleanup(); | |
651 | |
652 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); | |
653 try { | |
654 // Passing index avoid a race condition when this method is | |
655 // called after the user has selected another tab. | |
656 // Pass the anchor that initiated this request allows | |
657 // loadError to manipulate the tab content panel via $(a.hash) | |
658 o.ajaxOptions.error( xhr, s, index, a ); | |
659 } | |
660 catch ( e ) {} | |
661 } | |
662 } ) ); | |
663 | |
664 // last, so that load event is fired before show... | |
665 self.element.dequeue( "tabs" ); | |
666 | |
667 return this; | |
668 }, | |
669 | |
670 abort: function() { | |
671 // stop possibly running animations | |
672 this.element.queue( [] ); | |
673 this.panels.stop( false, true ); | |
674 | |
675 // "tabs" queue must not contain more than two elements, | |
676 // which are the callbacks for the latest clicked tab... | |
677 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) ); | |
678 | |
679 // terminate pending requests from other tabs | |
680 if ( this.xhr ) { | |
681 this.xhr.abort(); | |
682 delete this.xhr; | |
683 } | |
684 | |
685 // take care of tab labels | |
686 this._cleanup(); | |
687 return this; | |
688 }, | |
689 | |
690 url: function( index, url ) { | |
691 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url ); | |
692 return this; | |
693 }, | |
694 | |
695 length: function() { | |
696 return this.anchors.length; | |
697 } | |
698 }); | |
699 | |
700 $.extend( $.ui.tabs, { | |
701 version: "1.8.14" | |
702 }); | |
703 | |
704 /* | |
705 * Tabs Extensions | |
706 */ | |
707 | |
708 /* | |
709 * Rotate | |
710 */ | |
711 $.extend( $.ui.tabs.prototype, { | |
712 rotation: null, | |
713 rotate: function( ms, continuing ) { | |
714 var self = this, | |
715 o = this.options; | |
716 | |
717 var rotate = self._rotate || ( self._rotate = function( e ) { | |
718 clearTimeout( self.rotation ); | |
719 self.rotation = setTimeout(function() { | |
720 var t = o.selected; | |
721 self.select( ++t < self.anchors.length ? t : 0 ); | |
722 }, ms ); | |
723 | |
724 if ( e ) { | |
725 e.stopPropagation(); | |
726 } | |
727 }); | |
728 | |
729 var stop = self._unrotate || ( self._unrotate = !continuing | |
730 ? function(e) { | |
731 if (e.clientX) { // in case of a true click | |
732 self.rotate(null); | |
733 } | |
734 } | |
735 : function( e ) { | |
736 t = o.selected; | |
737 rotate(); | |
738 }); | |
739 | |
740 // start rotation | |
741 if ( ms ) { | |
742 this.element.bind( "tabsshow", rotate ); | |
743 this.anchors.bind( o.event + ".tabs", stop ); | |
744 rotate(); | |
745 // stop rotation | |
746 } else { | |
747 clearTimeout( self.rotation ); | |
748 this.element.unbind( "tabsshow", rotate ); | |
749 this.anchors.unbind( o.event + ".tabs", stop ); | |
750 delete this._rotate; | |
751 delete this._unrotate; | |
752 } | |
753 | |
754 return this; | |
755 } | |
756 }); | |
757 | |
758 })( jQuery ); |