Changeset 4672 for freepbx/branches

Show
Ignore:
Timestamp:
08/04/07 11:40:59 (6 years ago)
Author:
p_lindheimer
Message:

replace jquery.tabs.js with unpacked version

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • freepbx/branches/2.3/amp_conf/htdocs/admin/common/jquery.tabs.js

    r4348 r4672  
    1212 * Version: 2.7.4 
    1313 */ 
    14 eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4($){$.2k({A:{2r:0}});$.1E.A=4(x,w){2(V x==\'2V\')w=x;w=$.2k({K:(x&&V x==\'1Z\'&&x>0)?--x:0,13:C,I:$.1e?2i:O,1b:O,1o:\'2U&#2O;\',22:\'1b-2D-\',1s:C,1l:C,1i:C,1y:C,1x:\'2t\',2q:C,2n:C,2l:O,2j:C,1f:C,1c:C,1u:\'A-1O\',L:\'A-2a\',18:\'A-13\',19:\'A-24\',1q:\'A-1H\',1K:\'A-2J\',20:\'Z\'},w||{});$.8.1C=$.8.Q&&($.8.1Y&&$.8.1Y<7||/6.0/.2z(2x.2w));4 1F(){1V(0,0)}F 5.S(4(){3 p=5;3 r=$(\'10.\'+w.1u,p);r=r.W()&&r||$(\'>10:9(0)\',p);3 j=$(\'a\',r);2(w.1b){j.S(4(){3 c=w.22+(++$.A.2r),B=\'#\'+c,2g=5.1P;5.1P=B;$(\'<Z P="\'+c+\'" 33="\'+w.19+\'"></Z>\').2e(p);$(5).14(\'1N\',4(e,a){3 b=$(5).J(w.1K),Y=$(\'Y\',5)[0],27=Y.1J;2(w.1o){Y.1J=\'<26>\'+w.1o+\'</26>\'}1p(4(){$(B).2S(2g,4(){2(w.1o){Y.1J=27}b.1a(w.1K);a&&a()})},0)})})}3 n=$(\'Z.\'+w.19,p);n=n.W()&&n||$(\'>\'+w.20,p);r.T(\'.\'+w.1u)||r.J(w.1u);n.S(4(){3 a=$(5);a.T(\'.\'+w.19)||a.J(w.19)});3 s=$(\'z\',r).21($(\'z.\'+w.L,r)[0]);2(s>=0){w.K=s}2(1d.B){j.S(4(i){2(5.B==1d.B){w.K=i;2(($.8.Q||$.8.2E)&&!w.1b){3 a=$(1d.B);3 b=a.17(\'P\');a.17(\'P\',\'\');1p(4(){a.17(\'P\',b)},2C)}1F();F O}})}2($.8.Q){1F()}n.16(\':9(\'+w.K+\')\').1D().1m().2B(\':9(\'+w.K+\')\').J(w.1q);$(\'z\',r).1a(w.L).9(w.K).J(w.L);j.9(w.K).N(\'1N\').1m();2(w.2l){3 l=4(d){3 c=$.2A(n.1k(),4(a){3 h,1A=$(a);2(d){2($.8.1C){a.11.2y(\'1X\');a.11.G=\'\';a.1j=C}h=1A.H({\'1h-G\':\'\'}).G()}E{h=1A.G()}F h}).2v(4(a,b){F b-a});2($.8.1C){n.S(4(){5.1j=c[0]+\'1W\';5.11.2u(\'1X\',\'5.11.G = 5.1j ? 5.1j : "2s"\')})}E{n.H({\'1h-G\':c[0]+\'1W\'})}};l();3 q=p.1U;3 m=p.1v;3 v=$(\'#A-2p-2o-W\').1k(0)||$(\'<Y P="A-2p-2o-W">M</Y>\').H({1T:\'2m\',39:\'38\',37:\'36\'}).2e(U.1S).1k(0);3 o=v.1v;35(4(){3 b=p.1U;3 a=p.1v;3 c=v.1v;2(a>m||b!=q||c!=o){l((b>q||c<o));q=b;m=a;o=c}},34)}3 u={},12={},1R=w.2q||w.1x,1Q=w.2n||w.1x;2(w.1l||w.1s){2(w.1l){u[\'G\']=\'1D\';12[\'G\']=\'1H\'}2(w.1s){u[\'X\']=\'1D\';12[\'X\']=\'1H\'}}E{2(w.1i){u=w.1i}E{u[\'1h-2h\']=0;1R=1}2(w.1y){12=w.1y}E{12[\'1h-2h\']=0;1Q=1}}3 t=w.2j,1f=w.1f,1c=w.1c;j.14(\'2f\',4(){3 c=$(5).15(\'z:9(0)\');2(p.1t||c.T(\'.\'+w.L)||c.T(\'.\'+w.18)){F O}3 a=5.B;2($.8.Q){$(5).N(\'1g\');2(w.I){$.1e.1w(a);1d.B=a.1B(\'#\',\'\')}}E 2($.8.1z){3 b=$(\'<2d 32="\'+a+\'"><Z><31 30="2c" 2Z="h" /></Z></2d>\').1k(0);b.2c();$(5).N(\'1g\');2(w.I){$.1e.1w(a)}}E{2(w.I){1d.B=a.1B(\'#\',\'\')}E{$(5).N(\'1g\')}}});j.14(\'1M\',4(){3 a=$(5).15(\'z:9(0)\');2($.8.1z){a.1n({X:0},1,4(){a.H({X:\'\'})})}a.J(w.18)});2(w.13&&w.13.1L){29(3 i=0,k=w.13.1L;i<k;i++){j.9(--w.13[i]).N(\'1M\').1m()}};j.14(\'28\',4(){3 a=$(5).15(\'z:9(0)\');a.1a(w.18);2($.8.1z){a.1n({X:1},1,4(){a.H({X:\'\'})})}});j.14(\'1g\',4(e){3 g=e.2Y;3 d=5,z=$(5).15(\'z:9(0)\'),D=$(5.B),R=n.16(\':2X\');2(p[\'1t\']||z.T(\'.\'+w.L)||z.T(\'.\'+w.18)||V t==\'4\'&&t(5,D[0],R[0])===O){5.25();F O}p[\'1t\']=2i;2(D.W()){2($.8.Q&&w.I){3 c=5.B.1B(\'#\',\'\');D.17(\'P\',\'\');1p(4(){D.17(\'P\',c)},0)}3 f={1T:\'\',2T:\'\',G:\'\'};2(!$.8.Q){f[\'X\']=\'\'}4 1I(){2(w.I&&g){$.1e.1w(d.B)}R.1n(12,1Q,4(){$(d).15(\'z:9(0)\').J(w.L).2R().1a(w.L);R.J(w.1q).H(f);2(V 1f==\'4\'){1f(d,D[0],R[0])}2(!(w.1l||w.1s||w.1i)){D.H(\'1T\',\'2m\')}D.1n(u,1R,4(){D.1a(w.1q).H(f);2($.8.Q){R[0].11.16=\'\';D[0].11.16=\'\'}2(V 1c==\'4\'){1c(d,D[0],R[0])}p[\'1t\']=C})})}2(!w.1b){1I()}E{$(d).N(\'1N\',[1I])}}E{2Q(\'2P T 2W 2N 24.\')}3 a=1G.2M||U.1r&&U.1r.23||U.1S.23||0;3 b=1G.2L||U.1r&&U.1r.2b||U.1S.2b||0;1p(4(){1G.1V(a,b)},0);5.25();F w.I&&!!g});2(w.I){$.1e.2K(4(){j.9(w.K).N(\'1g\').1m()})}})};3 y=[\'2f\',\'1M\',\'28\'];29(3 i=0;i<y.1L;i++){$.1E[y[i]]=(4(d){F 4(c){F 5.S(4(){3 b=$(\'10.A-1O\',5);b=b.W()&&b||$(\'>10:9(0)\',5);3 a;2(!c||V c==\'1Z\'){a=$(\'z a\',b).9((c&&c>0&&c-1||0))}E 2(V c==\'2I\'){a=$(\'z a[@1P$="#\'+c+\'"]\',b)}a.N(d)})}})(y[i])}$.1E.2H=4(){3 c=[];5.S(4(){3 a=$(\'10.A-1O\',5);a=a.W()&&a||$(\'>10:9(0)\',5);3 b=$(\'z\',a);c.2G(b.21(b.16(\'.A-2a\')[0])+1)});F c[0]}})(2F);',62,196,'||if|var|function|this|||browser|eq||||||||||||||||||||||||||li|tabs|hash|null|toShow|else|return|height|css|bookmarkable|addClass|initial|selectedClass||trigger|false|id|msie|toHide|each|is|document|typeof|size|opacity|span|div|ul|style|hideAnim|disabled|bind|parents|filter|attr|disabledClass|containerClass|removeClass|remote|onShow|location|ajaxHistory|onHide|click|min|fxShow|minHeight|get|fxSlide|end|animate|spinner|setTimeout|hideClass|documentElement|fxFade|locked|navClass|offsetHeight|update|fxSpeed|fxHide|safari|jq|replace|msie6|show|fn|unFocus|window|hide|switchTab|innerHTML|loadingClass|length|disableTab|loadRemoteTab|nav|href|hideSpeed|showSpeed|body|display|offsetWidth|scrollTo|px|behaviour|version|number|tabStruct|index|hashPrefix|scrollLeft|container|blur|em|tabTitle|enableTab|for|selected|scrollTop|submit|form|appendTo|triggerTab|url|width|true|onClick|extend|fxAutoHeight|block|fxHideSpeed|font|watch|fxShowSpeed|remoteCount|1px|normal|setExpression|sort|userAgent|navigator|removeExpression|test|map|not|500|tab|opera|jQuery|push|activeTab|string|loading|initialize|pageYOffset|pageXOffset|such|8230|There|alert|siblings|load|overflow|Loading|object|no|visible|clientX|value|type|input|action|class|50|setInterval|hidden|visibility|absolute|position'.split('|'),0,{})) 
     14 
     15(function($) { // block scope 
     16 
     17$.extend({ 
     18    tabs: { 
     19        remoteCount: 0 // TODO in Tabs 3 this is going to be more cleanly in one single namespace 
     20    } 
     21}); 
     22 
     23/** 
     24 * Create an accessible, unobtrusive tab interface based on a particular HTML structure. 
     25 * 
     26 * The underlying HTML has to look like this: 
     27 * 
     28 * <div id="container"> 
     29 *     <ul> 
     30 *         <li><a href="#fragment-1">Section 1</a></li> 
     31 *         <li><a href="#fragment-2">Section 2</a></li> 
     32 *         <li><a href="#fragment-3">Section 3</a></li> 
     33 *     </ul> 
     34 *     <div id="fragment-1"> 
     35 * 
     36 *     </div> 
     37 *     <div id="fragment-2"> 
     38 * 
     39 *     </div> 
     40 *     <div id="fragment-3"> 
     41 * 
     42 *     </div> 
     43 * </div> 
     44 * 
     45 * Each anchor in the unordered list points directly to a section below represented by one of the 
     46 * divs (the URI in the anchor's href attribute refers to the fragment with the corresponding id). 
     47 * Because such HTML structure is fully functional on its own, e.g. without JavaScript, the tab 
     48 * interface is accessible and unobtrusive. 
     49 * 
     50 * A tab is also bookmarkable via hash in the URL. Use the History/Remote plugin (Tabs will 
     51 * auto-detect its presence) to fix the back (and forward) button. 
     52 * 
     53 * @example $('#container').tabs(); 
     54 * @desc Create a basic tab interface. 
     55 * @example $('#container').tabs(2); 
     56 * @desc Create a basic tab interface with the second tab initially activated. 
     57 * @example $('#container').tabs({disabled: [3, 4]}); 
     58 * @desc Create a tab interface with the third and fourth tab being disabled. 
     59 * @example $('#container').tabs({fxSlide: true}); 
     60 * @desc Create a tab interface that uses slide down/up animations for showing/hiding tab 
     61 *       content upon tab switching. 
     62 * 
     63 * @param Number initial An integer specifying the position of the tab (no zero-based index) that 
     64 *                       gets activated at first (on page load). Two alternative ways to specify 
     65 *                       the active tab will overrule this argument. First a li element 
     66 *                       (representing one single tab) belonging to the selected tab class, e.g. 
     67 *                       set the selected tab class (default: "tabs-selected", see option 
     68 *                       selectedClass) for one of the unordered li elements in the HTML source. 
     69 *                       In addition if a fragment identifier/hash in the URL of the page refers 
     70 *                       to the id of a tab container of a tab interface the corresponding tab will 
     71 *                       be activated and both the initial argument as well as an eventually 
     72 *                       declared class attribute will be overruled. Defaults to 1 if omitted. 
     73 * @param Object settings An object literal containing key/value pairs to provide optional settings. 
     74 * @option Array<Number> disabled An array containing the position of the tabs (no zero-based index) 
     75 *                                that should be disabled on initialization. Default value: null. 
     76 *                                A tab can also be disabled by simply adding the disabling class 
     77 *                                (default: "tabs-disabled", see option disabledClass) to the li 
     78 *                                element representing that particular tab. 
     79 * @option Boolean bookmarkable Boolean flag indicating if support for bookmarking and history (via 
     80 *                              changing hash in the URL of the browser) is enabled. Default value: 
     81 *                              false, unless the History/Remote plugin is included. In that case the 
     82 *                              default value becomes true. @see $.ajaxHistory.initialize 
     83 * @option Boolean remote Boolean flag indicating that tab content has to be loaded remotely from 
     84 *                        the url given in the href attribute of the tab menu anchor elements. 
     85 * @option String spinner The content of this string is shown in a tab while remote content is loading. 
     86 *                        Insert plain text as well as an img here. To turn off this notification 
     87 *                        pass an empty string or null. Default: "Loading&#8230;". 
     88 * @option String hashPrefix A String that is used for constructing the hash the link's href attribute 
     89 *                           of a remote tab gets altered to, such as "#remote-1". 
     90 *                           Default value: "remote-tab-". 
     91 * @option Boolean fxFade Boolean flag indicating whether fade in/out animations are used for tab 
     92 *                        switching. Can be combined with fxSlide. Will overrule fxShow/fxHide. 
     93 *                        Default value: false. 
     94 * @option Boolean fxSlide Boolean flag indicating whether slide down/up animations are used for tab 
     95 *                         switching. Can be combined with fxFade. Will overrule fxShow/fxHide. 
     96 *                         Default value: false. 
     97 * @option String|Number fxSpeed A string representing one of the three predefined speeds ("slow", 
     98 *                               "normal", or "fast") or the number of milliseconds (e.g. 1000) to 
     99 *                               run an animation. Default value: "normal". 
     100 * @option Object fxShow An object literal of the form jQuery's animate function expects for making 
     101 *                       your own, custom animation to reveal a tab upon tab switch. Unlike fxFade 
     102 *                       or fxSlide this animation is independent from an optional hide animation. 
     103 *                       Default value: null. @see animate 
     104 * @option Object fxHide An object literal of the form jQuery's animate function expects for making 
     105 *                       your own, custom animation to hide a tab upon tab switch. Unlike fxFade 
     106 *                       or fxSlide this animation is independent from an optional show animation. 
     107 *                       Default value: null. @see animate 
     108 * @option String|Number fxShowSpeed A string representing one of the three predefined speeds 
     109 *                                   ("slow", "normal", or "fast") or the number of milliseconds 
     110 *                                   (e.g. 1000) to run the animation specified in fxShow. 
     111 *                                   Default value: fxSpeed. 
     112 * @option String|Number fxHideSpeed A string representing one of the three predefined speeds 
     113 *                                   ("slow", "normal", or "fast") or the number of milliseconds 
     114 *                                   (e.g. 1000) to run the animation specified in fxHide. 
     115 *                                   Default value: fxSpeed. 
     116 * @option Boolean fxAutoHeight Boolean flag that if set to true causes all tab heights 
     117 *                              to be constant (being the height of the tallest tab). 
     118 *                              Default value: false. 
     119 * @option Function onClick A function to be invoked upon tab switch, immediatly after a tab has 
     120 *                          been clicked, e.g. before the other's tab content gets hidden. The 
     121 *                          function gets passed three arguments: the first one is the clicked 
     122 *                          tab (e.g. an anchor element), the second one is the DOM element 
     123 *                          containing the content of the clicked tab (e.g. the div), the third 
     124 *                          argument is the one of the tab that gets hidden. If this callback 
     125 *                          returns false, the tab switch is canceled (use to disallow tab 
     126 *                          switching for the reason of a failed form validation for example). 
     127 *                          Default value: null. 
     128 * @option Function onHide A function to be invoked upon tab switch, immediatly after one tab's 
     129 *                         content got hidden (with or without an animation) and right before the 
     130 *                         next tab is revealed. The function gets passed three arguments: the 
     131 *                         first one is the clicked tab (e.g. an anchor element), the second one 
     132 *                         is the DOM element containing the content of the clicked tab, (e.g. the 
     133 *                         div), the third argument is the one of the tab that gets hidden. 
     134 *                         Default value: null. 
     135 * @option Function onShow A function to be invoked upon tab switch. This function is invoked 
     136 *                         after the new tab has been revealed, e.g. after the switch is completed. 
     137 *                         The function gets passed three arguments: the first one is the clicked 
     138 *                         tab (e.g. an anchor element), the second one is the DOM element 
     139 *                         containing the content of the clicked tab, (e.g. the div), the third 
     140 *                         argument is the one of the tab that gets hidden. Default value: null. 
     141 * @option String navClass A CSS class that is used to identify the tabs unordered list by class if 
     142 *                         the required HTML structure differs from the default one. 
     143 *                         Default value: "tabs-nav". 
     144 * @option String selectedClass The CSS class attached to the li element representing the 
     145 *                              currently selected (active) tab. Default value: "tabs-selected". 
     146 * @option String disabledClass The CSS class attached to the li element representing a disabled 
     147 *                              tab. Default value: "tabs-disabled". 
     148 * @option String containerClass A CSS class that is used to identify tab containers by class if 
     149 *                               the required HTML structure differs from the default one. 
     150 *                               Default value: "tabs-container". 
     151 * @option String hideClass The CSS class used for hiding inactive tabs. A class is used instead 
     152 *                          of "display: none" in the style attribute to maintain control over 
     153 *                          visibility in other media types than screen, most notably print. 
     154 *                          Default value: "tabs-hide". 
     155 * @option String loadingClass The CSS class used for indicating that an Ajax tab is currently 
     156 *                             loading, for example by showing a spinner. 
     157 *                             Default value: "tabs-loading". 
     158 * @option String tabStruct @deprecated A CSS selector or basic XPath expression reflecting a 
     159 *                          nested HTML structure that is different from the default single div 
     160 *                          structure (one div with an id inside the overall container holds one 
     161 *                          tab's content). If for instance an additional div is required to wrap 
     162 *                          up the several tab containers such a structure is expressed by "div>div". 
     163 *                          Default value: "div". 
     164 * @type jQuery 
     165 * 
     166 * @name tabs 
     167 * @cat Plugins/Tabs 
     168 * @author Klaus Hartl/klaus.hartl@stilbuero.de 
     169 */ 
     170$.fn.tabs = function(initial, settings) { 
     171 
     172    // settings 
     173    if (typeof initial == 'object') settings = initial; // no initial tab given but a settings object 
     174    settings = $.extend({ 
     175        initial: (initial && typeof initial == 'number' && initial > 0) ? --initial : 0, 
     176        disabled: null, 
     177        bookmarkable: $.ajaxHistory ? true : false, 
     178        remote: false, 
     179        spinner: 'Loading&#8230;', 
     180        hashPrefix: 'remote-tab-', 
     181        fxFade: null, 
     182        fxSlide: null, 
     183        fxShow: null, 
     184        fxHide: null, 
     185        fxSpeed: 'normal', 
     186        fxShowSpeed: null, 
     187        fxHideSpeed: null, 
     188        fxAutoHeight: false, 
     189        onClick: null, 
     190        onHide: null, 
     191        onShow: null, 
     192        navClass: 'tabs-nav', 
     193        selectedClass: 'tabs-selected', 
     194        disabledClass: 'tabs-disabled', 
     195        containerClass: 'tabs-container', 
     196        hideClass: 'tabs-hide', 
     197        loadingClass: 'tabs-loading', 
     198        tabStruct: 'div' 
     199    }, settings || {}); 
     200 
     201    $.browser.msie6 = $.browser.msie && ($.browser.version && $.browser.version < 7 || /6.0/.test(navigator.userAgent));     
     202 
     203    // helper to prevent scroll to fragment 
     204    function unFocus() { 
     205        scrollTo(0, 0); 
     206    } 
     207 
     208    // initialize tabs 
     209    return this.each(function() { 
     210 
     211        // remember wrapper for later 
     212        var container = this; 
     213 
     214        // setup nav 
     215        var nav = $('ul.' + settings.navClass, container); 
     216        nav = nav.size() && nav || $('>ul:eq(0)', container); // fallback to default structure 
     217        var tabs = $('a', nav); 
     218 
     219        // prepare remote tabs 
     220        if (settings.remote) { 
     221            tabs.each(function() { 
     222                var id = settings.hashPrefix + (++$.tabs.remoteCount), hash = '#' + id, url = this.href; 
     223                this.href = hash; 
     224                $('<div id="' + id + '" class="' + settings.containerClass + '"></div>').appendTo(container); 
     225 
     226                $(this).bind('loadRemoteTab', function(e, callback) { 
     227                    var $$ = $(this).addClass(settings.loadingClass), span = $('span', this)[0], tabTitle = span.innerHTML; 
     228                    if (settings.spinner) { 
     229                        // TODO if spinner is image 
     230                        span.innerHTML = '<em>' + settings.spinner + '</em>'; // WARNING: html(...) crashes Safari with jQuery 1.1.2 
     231                    } 
     232                    setTimeout(function() { // Timeout is again required in IE, "wait" for id being restored 
     233                        $(hash).load(url, function() { 
     234                            if (settings.spinner) { 
     235                                span.innerHTML = tabTitle; // WARNING: html(...) crashes Safari with jQuery 1.1.2 
     236                            } 
     237                            $$.removeClass(settings.loadingClass); 
     238                            callback && callback(); 
     239                        }); 
     240                    }, 0); 
     241                }); 
     242 
     243            }); 
     244        } 
     245 
     246        // set up containers 
     247        var containers = $('div.' + settings.containerClass, container); 
     248        containers = containers.size() && containers || $('>' + settings.tabStruct, container); // fallback to default structure 
     249 
     250        // attach classes for styling if not present 
     251        nav.is('.' + settings.navClass) || nav.addClass(settings.navClass); 
     252        containers.each(function() { 
     253            var $$ = $(this); 
     254            $$.is('.' + settings.containerClass) || $$.addClass(settings.containerClass); 
     255        }); 
     256 
     257        // try to retrieve active tab from class in HTML 
     258        var hasSelectedClass = $('li', nav).index( $('li.' + settings.selectedClass, nav)[0] ); 
     259        if (hasSelectedClass >= 0) { 
     260           settings.initial = hasSelectedClass; 
     261        } 
     262 
     263        // try to retrieve active tab from hash in url, will override class in HTML 
     264        if (location.hash) { 
     265            tabs.each(function(i) { 
     266                if (this.hash == location.hash) { 
     267                    settings.initial = i; 
     268                    // prevent page scroll to fragment 
     269                    if (($.browser.msie || $.browser.opera) && !settings.remote) { 
     270                        var toShow = $(location.hash); 
     271                        var toShowId = toShow.attr('id'); 
     272                        toShow.attr('id', ''); 
     273                        setTimeout(function() { 
     274                            toShow.attr('id', toShowId); // restore id 
     275                        }, 500); 
     276                    } 
     277                    unFocus(); 
     278                    return false; // break 
     279                } 
     280            }); 
     281        } 
     282        if ($.browser.msie) { 
     283            unFocus(); // fix IE focussing bottom of the page for some unknown reason 
     284        } 
     285 
     286        // highlight tab accordingly 
     287        containers.filter(':eq(' + settings.initial + ')').show().end().not(':eq(' + settings.initial + ')').addClass(settings.hideClass); 
     288        $('li', nav).removeClass(settings.selectedClass).eq(settings.initial).addClass(settings.selectedClass); // we need to remove classes eventually if hash takes precedence over class 
     289        // trigger load of initial tab 
     290        tabs.eq(settings.initial).trigger('loadRemoteTab').end(); 
     291 
     292        // setup auto height 
     293        if (settings.fxAutoHeight) { 
     294            // helper 
     295            var _setAutoHeight = function(reset) { 
     296                // get tab heights in top to bottom ordered array 
     297                var heights = $.map(containers.get(), function(el) { 
     298                    var h, jq = $(el); 
     299                    if (reset) { 
     300                        if ($.browser.msie6) { 
     301                            el.style.removeExpression('behaviour'); 
     302                            el.style.height = ''; 
     303                            el.minHeight = null; 
     304                        } 
     305                        h = jq.css({'min-height': ''}).height(); // use jQuery's height() to get hidden element values 
     306                    } else { 
     307                        h = jq.height(); // use jQuery's height() to get hidden element values 
     308                    } 
     309                    return h; 
     310                }).sort(function(a, b) { 
     311                    return b - a; 
     312                }); 
     313                if ($.browser.msie6) { 
     314                    containers.each(function() { 
     315                        this.minHeight = heights[0] + 'px'; 
     316                        this.style.setExpression('behaviour', 'this.style.height = this.minHeight ? this.minHeight : "1px"'); // using an expression to not make print styles useless 
     317                    }); 
     318                } else { 
     319                    containers.css({'min-height': heights[0] + 'px'}); 
     320                } 
     321            }; 
     322            // call once for initialization 
     323            _setAutoHeight(); 
     324            // trigger auto height adjustment if needed 
     325            var cachedWidth = container.offsetWidth; 
     326            var cachedHeight = container.offsetHeight; 
     327            var watchFontSize = $('#tabs-watch-font-size').get(0) || $('<span id="tabs-watch-font-size">M</span>').css({display: 'block', position: 'absolute', visibility: 'hidden'}).appendTo(document.body).get(0); 
     328            var cachedFontSize = watchFontSize.offsetHeight; 
     329            setInterval(function() { 
     330                var currentWidth = container.offsetWidth; 
     331                var currentHeight = container.offsetHeight; 
     332                var currentFontSize = watchFontSize.offsetHeight; 
     333                if (currentHeight > cachedHeight || currentWidth != cachedWidth || currentFontSize != cachedFontSize) { 
     334                    _setAutoHeight((currentWidth > cachedWidth || currentFontSize < cachedFontSize)); // if heights gets smaller reset min-height 
     335                    cachedWidth = currentWidth; 
     336                    cachedHeight = currentHeight; 
     337                    cachedFontSize = currentFontSize; 
     338                } 
     339            }, 50); 
     340        } 
     341 
     342        // setup animations 
     343        var showAnim = {}, hideAnim = {}, showSpeed = settings.fxShowSpeed || settings.fxSpeed, hideSpeed = settings.fxHideSpeed || settings.fxSpeed; 
     344        if (settings.fxSlide || settings.fxFade) { 
     345            if (settings.fxSlide) { 
     346                showAnim['height'] = 'show'; 
     347                hideAnim['height'] = 'hide'; 
     348            } 
     349            if (settings.fxFade) { 
     350                showAnim['opacity'] = 'show'; 
     351                hideAnim['opacity'] = 'hide'; 
     352            } 
     353        } else { 
     354            if (settings.fxShow) { 
     355                showAnim = settings.fxShow; 
     356            } else { // use some kind of animation to prevent browser scrolling to the tab 
     357                showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox 
     358                showSpeed = 1; // as little as 1 is sufficient 
     359            } 
     360            if (settings.fxHide) { 
     361                hideAnim = settings.fxHide; 
     362            } else { // use some kind of animation to prevent browser scrolling to the tab 
     363                hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox 
     364                hideSpeed = 1; // as little as 1 is sufficient 
     365            } 
     366        } 
     367 
     368        // callbacks 
     369        var onClick = settings.onClick, onHide = settings.onHide, onShow = settings.onShow; 
     370 
     371        // attach activateTab event, required for activating a tab programmatically 
     372        tabs.bind('triggerTab', function() { 
     373 
     374            // if the tab is already selected or disabled or animation is still running stop here 
     375            var li = $(this).parents('li:eq(0)'); 
     376            if (container.locked || li.is('.' + settings.selectedClass) || li.is('.' + settings.disabledClass)) { 
     377                return false; 
     378            } 
     379 
     380            var hash = this.hash; 
     381 
     382            if ($.browser.msie) { 
     383 
     384                $(this).trigger('click'); 
     385                if (settings.bookmarkable) { 
     386                    $.ajaxHistory.update(hash); 
     387                    location.hash = hash.replace('#', ''); 
     388                } 
     389 
     390            } else if ($.browser.safari) { 
     391 
     392                // Simply setting location.hash puts Safari into the eternal load state... ugh! Submit a form instead. 
     393                var tempForm = $('<form action="' + hash + '"><div><input type="submit" value="h" /></div></form>').get(0); // no need to append it to the body 
     394                tempForm.submit(); // does not trigger the form's submit event... 
     395                $(this).trigger('click'); // ...thus do stuff here 
     396                if (settings.bookmarkable) { 
     397                    $.ajaxHistory.update(hash); 
     398                } 
     399 
     400            } else { 
     401 
     402                if (settings.bookmarkable) { 
     403                    location.hash = hash.replace('#', ''); 
     404                } else { 
     405                    $(this).trigger('click'); 
     406                } 
     407 
     408            } 
     409 
     410        }); 
     411 
     412        // attach disable event, required for disabling a tab 
     413        tabs.bind('disableTab', function() { 
     414            var li = $(this).parents('li:eq(0)'); 
     415            if ($.browser.safari) { /* fix opacity of tab after disabling in Safari... */ 
     416                li.animate({ opacity: 0 }, 1, function() { 
     417                   li.css({opacity: ''}); 
     418                }); 
     419            } 
     420            li.addClass(settings.disabledClass); 
     421 
     422        }); 
     423 
     424        // disabled from settings 
     425        if (settings.disabled && settings.disabled.length) { 
     426            for (var i = 0, k = settings.disabled.length; i < k; i++) { 
     427                tabs.eq(--settings.disabled[i]).trigger('disableTab').end(); 
     428            } 
     429        }; 
     430 
     431        // attach enable event, required for reenabling a tab 
     432        tabs.bind('enableTab', function() { 
     433            var li = $(this).parents('li:eq(0)'); 
     434            li.removeClass(settings.disabledClass); 
     435            if ($.browser.safari) { /* fix disappearing tab after enabling in Safari... */ 
     436                li.animate({ opacity: 1 }, 1, function() { 
     437                    li.css({opacity: ''}); 
     438                }); 
     439            } 
     440        }); 
     441 
     442        // attach click event 
     443        tabs.bind('click', function(e) { 
     444 
     445            var trueClick = e.clientX; // add to history only if true click occured, not a triggered click 
     446            var clicked = this, li = $(this).parents('li:eq(0)'), toShow = $(this.hash), toHide = containers.filter(':visible'); 
     447 
     448            // if animation is still running, tab is selected or disabled or onClick callback returns false stop here 
     449            // check if onClick returns false last so that it is not executed for a disabled tab 
     450            if (container['locked'] || li.is('.' + settings.selectedClass) || li.is('.' + settings.disabledClass) || typeof onClick == 'function' && onClick(this, toShow[0], toHide[0]) === false) { 
     451                this.blur(); 
     452                return false; 
     453            } 
     454 
     455            container['locked'] = true; 
     456 
     457            // show new tab 
     458            if (toShow.size()) { 
     459 
     460                // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled 
     461                if ($.browser.msie && settings.bookmarkable) { 
     462                    var toShowId = this.hash.replace('#', ''); 
     463                    toShow.attr('id', ''); 
     464                    setTimeout(function() { 
     465                        toShow.attr('id', toShowId); // restore id 
     466                    }, 0); 
     467                } 
     468 
     469                var resetCSS = { display: '', overflow: '', height: '' }; 
     470                if (!$.browser.msie) { // not in IE to prevent ClearType font issue 
     471                    resetCSS['opacity'] = ''; 
     472                } 
     473                 
     474                // switch tab, animation prevents browser scrolling to the fragment 
     475                function switchTab() { 
     476                    if (settings.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click 
     477                        $.ajaxHistory.update(clicked.hash); 
     478                    } 
     479                    toHide.animate(hideAnim, hideSpeed, function() { // 
     480                        $(clicked).parents('li:eq(0)').addClass(settings.selectedClass).siblings().removeClass(settings.selectedClass); 
     481                        toHide.addClass(settings.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.                         
     482                        if (typeof onHide == 'function') { 
     483                            onHide(clicked, toShow[0], toHide[0]); 
     484                        } 
     485                        if (!(settings.fxSlide || settings.fxFade || settings.fxShow)) { 
     486                            toShow.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers 
     487                        } 
     488                        toShow.animate(showAnim, showSpeed, function() { 
     489                            toShow.removeClass(settings.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. 
     490                            if ($.browser.msie) { 
     491                                toHide[0].style.filter = ''; 
     492                                toShow[0].style.filter = ''; 
     493                            } 
     494                            if (typeof onShow == 'function') { 
     495                                onShow(clicked, toShow[0], toHide[0]); 
     496                            } 
     497                            container['locked'] = null; 
     498                        }); 
     499                    }); 
     500                } 
     501 
     502                if (!settings.remote) { 
     503                    switchTab(); 
     504                } else { 
     505                    $(clicked).trigger('loadRemoteTab', [switchTab]); 
     506                } 
     507 
     508            } else { 
     509                alert('There is no such container.'); 
     510            } 
     511 
     512            // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash 
     513            var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0; 
     514            var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0; 
     515            setTimeout(function() { 
     516                window.scrollTo(scrollX, scrollY); 
     517            }, 0); 
     518 
     519            this.blur(); // prevent IE from keeping other link focussed when using the back button 
     520 
     521            return settings.bookmarkable && !!trueClick; // convert undefined to Boolean for IE 
     522 
     523        }); 
     524 
     525        // enable history support if bookmarking and history is turned on 
     526        if (settings.bookmarkable) { 
     527            $.ajaxHistory.initialize(function() { 
     528                tabs.eq(settings.initial).trigger('click').end(); 
     529            }); 
     530        } 
     531 
     532    }); 
     533 
     534}; 
     535 
     536/** 
     537 * Activate a tab programmatically with the given position (no zero-based index) 
     538 * or its id, e.g. the URL's fragment identifier/hash representing a tab, as if the tab 
     539 * itself were clicked. 
     540 * 
     541 * @example $('#container').triggerTab(2); 
     542 * @desc Activate the second tab of the tab interface contained in <div id="container">. 
     543 * @example $('#container').triggerTab(1); 
     544 * @desc Activate the first tab of the tab interface contained in <div id="container">. 
     545 * @example $('#container').triggerTab(); 
     546 * @desc Activate the first tab of the tab interface contained in <div id="container">. 
     547 * @example $('#container').triggerTab('fragment-2'); 
     548 * @desc Activate a tab via its URL fragment identifier representation. 
     549 * 
     550 * @param String|Number tab Either a string that matches the id of the tab (the URL's 
     551 *                          fragment identifier/hash representing a tab) or an integer 
     552 *                          specifying the position of the tab (no zero-based index) to 
     553 *                          be activated. If this parameter is omitted, the first tab 
     554 *                          will be activated. 
     555 * @type jQuery 
     556 * 
     557 * @name triggerTab 
     558 * @cat Plugins/Tabs 
     559 * @author Klaus Hartl/klaus.hartl@stilbuero.de 
     560 */ 
     561 
     562/** 
     563 * Disable a tab, so that clicking it has no effect. 
     564 * 
     565 * @example $('#container').disableTab(2); 
     566 * @desc Disable the second tab of the tab interface contained in <div id="container">. 
     567 * 
     568 * @param String|Number tab Either a string that matches the id of the tab (the URL's 
     569 *                          fragment identifier/hash representing a tab) or an integer 
     570 *                          specifying the position of the tab (no zero-based index) to 
     571 *                          be disabled. If this parameter is omitted, the first tab 
     572 *                          will be disabled. 
     573 * @type jQuery 
     574 * 
     575 * @name disableTab 
     576 * @cat Plugins/Tabs 
     577 * @author Klaus Hartl/klaus.hartl@stilbuero.de 
     578 */ 
     579 
     580/** 
     581 * Enable a tab that has been disabled. 
     582 * 
     583 * @example $('#container').enableTab(2); 
     584 * @desc Enable the second tab of the tab interface contained in <div id="container">. 
     585 * 
     586 * @param String|Number tab Either a string that matches the id of the tab (the URL's 
     587 *                          fragment identifier/hash representing a tab) or an integer 
     588 *                          specifying the position of the tab (no zero-based index) to 
     589 *                          be enabled. If this parameter is omitted, the first tab 
     590 *                          will be enabled. 
     591 * @type jQuery 
     592 * 
     593 * @name enableTab 
     594 * @cat Plugins/Tabs 
     595 * @author Klaus Hartl/klaus.hartl@stilbuero.de 
     596 */ 
     597 
     598var tabEvents = ['triggerTab', 'disableTab', 'enableTab']; 
     599for (var i = 0; i < tabEvents.length; i++) { 
     600    $.fn[tabEvents[i]] = (function(tabEvent) { 
     601        return function(tab) { 
     602            return this.each(function() { 
     603                var nav = $('ul.tabs-nav' , this); 
     604                nav = nav.size() && nav || $('>ul:eq(0)', this); // fallback to default structure 
     605                var a; 
     606                if (!tab || typeof tab == 'number') { 
     607                    a = $('li a', nav).eq((tab && tab > 0 && tab - 1 || 0)); // fall back to 0 
     608                } else if (typeof tab == 'string') { 
     609                    a = $('li a[@href$="#' + tab + '"]', nav); 
     610                } 
     611                a.trigger(tabEvent); 
     612            }); 
     613        }; 
     614    })(tabEvents[i]); 
     615
     616 
     617/** 
     618 * Get the position of the currently selected tab (no zero-based index). 
     619 * 
     620 * @example $('#container').activeTab(); 
     621 * @desc Get the position of the currently selected tab of an interface 
     622 * contained in <div id="container">. 
     623 * 
     624 * @type Number 
     625 * 
     626 * @name activeTab 
     627 * @cat Plugins/Tabs 
     628 * @author Klaus Hartl/klaus.hartl@stilbuero.de 
     629 */ 
     630 
     631$.fn.activeTab = function() { 
     632    var selectedTabs = []; 
     633    this.each(function() { 
     634        var nav = $('ul.tabs-nav' , this); 
     635        nav = nav.size() && nav || $('>ul:eq(0)', this); //fallback to default structure 
     636        var lis = $('li', nav); 
     637        selectedTabs.push(lis.index( lis.filter('.tabs-selected')[0] ) + 1); 
     638    }); 
     639    return selectedTabs[0]; 
     640}; 
     641 
     642})(jQuery);