/* * Tabs 3 - New Wave Tabs * * Copyright (c) 2007 Klaus Hartl (stilbuero.de) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. */(function($) {    // if the UI scope is not availalable, add it    $.ui = $.ui || {};    // tabs initialization    $.fn.tabs = function(initial, options) {        if (initial && initial.constructor == Object) { // shift arguments            options = initial;            initial = null;        }        options = options || {};        initial = initial && initial.constructor == Number && --initial || 0;        return this.each(function() {            new $.ui.tabs(this, $.extend(options, { initial: initial }));        });    };    // other chainable tabs methods    $.each(['Add', 'Remove', 'Enable', 'Disable', 'Click', 'Load'], function(i, method) {        $.fn['tabs' + method] = function() {            var args = arguments;            return this.each(function() {                var instance = $.ui.tabs.getInstance(this);                instance[method.toLowerCase()].apply(instance, args);            });        };    });    $.fn.tabsSelected = function() {        var selected = -1;        if (this[0]) {            var instance = $.ui.tabs.getInstance(this[0]),                $lis = $('li', this);            selected = $lis.index( $lis.filter('.' + instance.options.selectedClass)[0] );        }        return selected >= 0 ? ++selected : -1;    };    // tabs class    $.ui.tabs = function(el, options) {        this.source = el;        this.options = $.extend({            // basic setup            initial: 0,            event: 'click',            disabled: [],            // TODO bookmarkable: $.ajaxHistory ? true : false,            unselected: false,            unselect: options.unselected ? true : false,            // Ajax            spinner: 'Loading…',            cache: false,            idPrefix: 'tab-',            // animations            /*fxFade: null,            fxSlide: null,            fxShow: null,            fxHide: null,*/            fxSpeed: 'normal',            /*fxShowSpeed: null,            fxHideSpeed: null,*/            // callbacks            add: function() {},            remove: function() {},            enable: function() {},            disable: function() {},            click: function() {},            hide: function() {},            show: function() {},            load: function() {},            // CSS classes            navClass: 'ui-tabs-nav',            selectedClass: 'ui-tabs-selected',            disabledClass: 'ui-tabs-disabled',            containerClass: 'ui-tabs-container',            hideClass: 'ui-tabs-hide',            loadingClass: 'ui-tabs-loading'        }, options);        this.tabify(true);        // save instance for later        var uuid = 'tabs' + $.ui.tabs.prototype.count++;        $.ui.tabs.instances[uuid] = this;        $.data(el, 'tabsUUID', uuid);    };    // static    $.ui.tabs.instances = {};    $.ui.tabs.getInstance = function(el) {        return $.ui.tabs.instances[$.data(el, 'tabsUUID')];    };    // instance methods    $.extend($.ui.tabs.prototype, {        count: 0,        tabify: function(init) {            this.$tabs = $('a:first-child', this.source);            this.$containers = $([]);            var self = this, o = this.options;                        this.$tabs.each(function(i, a) {                // inline tab                if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash                    self.$containers = self.$containers.add(a.hash);                }                // remote tab                else {                    $.data(a, 'href', a.href);                    var id = a.title && a.title.replace(/\s/g, '_') || o.idPrefix + (self.count + 1) + '-' + (i + 1);                    a.href = '#' + id;                    self.$containers = self.$containers.add(                        $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')                            .insertAfter( self.$containers[i - 1] || self.source )                    );                }            });            if (init) {                // Try to retrieve initial tab from fragment identifier in url if present,                // otherwise try to find selected class attribute on <li>.                this.$tabs.each(function(i, a) {                    if (location.hash) {                        if (a.hash == location.hash) {                            o.initial = i;                            // prevent page scroll to fragment                            //if (($.browser.msie || $.browser.opera) && !o.remote) {                            if ($.browser.msie || $.browser.opera) {                                var $toShow = $(location.hash), toShowId = $toShow.attr('id');                                $toShow.attr('id', '');                                setTimeout(function() {                                    $toShow.attr('id', toShowId); // restore id                                }, 500);                            }                            scrollTo(0, 0);                            return false; // break                        }                    } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {                        o.initial = i;                        return false; // break                    }                });                // attach necessary classes for styling if not present                $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);                this.$containers.each(function() {                    var $this = $(this);                    $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);                });                // highlight tab                var $lis = $('li', this.source);                this.$containers.addClass(o.hideClass);                $lis.removeClass(o.selectedClass);                if (!o.unselected) {                    this.$containers.slice(o.initial, o.initial + 1).show();                    $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);                }                // load if remote tab                if ($.data(this.$tabs[o.initial], 'href')) {                    this.load(o.initial + 1, $.data(this.$tabs[o.initial], 'href'));                    if (o.cache) {                        $.removeData(this.$tabs[o.initial], 'href'); // if loaded once do not load them again                    }                }                // disabled tabs                for (var i = 0, position; position = o.disabled[i]; i++) {                    this.disable(position);                }            }            // setup animations            var showAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,                hideAnim = {}, hideSpeed = o.fxHideSpeed || o.fxSpeed;            if (o.fxSlide || o.fxFade) {                if (o.fxSlide) {                    showAnim['height'] = 'show';                    hideAnim['height'] = 'hide';                }                if (o.fxFade) {                    showAnim['opacity'] = 'show';                    hideAnim['opacity'] = 'hide';                }            } else {                if (o.fxShow) {                    showAnim = o.fxShow;                } else { // use some kind of animation to prevent browser scrolling to the tab                    showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox                    showSpeed = 1; // as little as 1 is sufficient                }                if (o.fxHide) {                    hideAnim = o.fxHide;                } else { // use some kind of animation to prevent browser scrolling to the tab                    hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox                    hideSpeed = 1; // as little as 1 is sufficient                }            }            // reset some styles to maintain print style sheets etc.            var resetCSS = { display: '', overflow: '', height: '' };            if (!$.browser.msie) { // not in IE to prevent ClearType font issue                resetCSS['opacity'] = '';            }            // Hide a tab, animation prevents browser scrolling to fragment,            // $show is optional.            function hideTab(clicked, $hide, $show) {                $hide.animate(hideAnim, hideSpeed, function() { //                    $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.                    if ($.browser.msie) {                        $hide[0].style.filter = '';                    }                    o.hide(clicked, $hide[0], $show && $show[0] || null);                    if ($show) {                        showTab(clicked, $show, $hide);                    }                });            }            // Show a tab, animation prevents browser scrolling to fragment,            // $hide is optional            function showTab(clicked, $show, $hide) {                if (!(o.fxSlide || o.fxFade || o.fxShow)) {                    $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers                }                $show.animate(showAnim, showSpeed, function() {                    $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.                    if ($.browser.msie) {                        $show[0].style.filter = '';                    }                    o.show(clicked, $show[0], $hide && $hide[0] || null);                });            }            // switch a tab            function switchTab(clicked, $hide, $show) {                /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click                    $.ajaxHistory.update(clicked.hash);                }*/                $(clicked).parents('li:eq(0)').addClass(o.selectedClass)                    .siblings().removeClass(o.selectedClass);                hideTab(clicked, $hide, $show);            }            // tab click handler            function tabClick(e) {                //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click                var $li = $(this).parents('li:eq(0)'),                    $hide = self.$containers.filter(':visible'),                    $show = $(this.hash);                // If tab is already selected and not unselectable or tab disabled or click callback returns false stop here.                // Check if click handler returns false last so that it is not executed for a disabled tab!                if (($li.is('.' + o.selectedClass) && !o.unselect) || $li.is('.' + o.disabledClass)                    || o.click(this, $show[0], $hide[0]) === false) {                    this.blur();                    return false;                }                                    // if tab may be closed                if (o.unselect) {                    if ($li.is('.' + o.selectedClass)) {                        $li.removeClass(o.selectedClass);                        self.$containers.stop();                        hideTab(this, $hide);                        this.blur();                        return false;                    } else if (!$hide.length) {                        $li.addClass(o.selectedClass);                        self.$containers.stop();                        showTab(this, $show);                        this.blur();                        return false;                    }                }                // stop possibly running animations                self.$containers.stop();                // show new tab                if ($show.length) {                    // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled                    /*if ($.browser.msie && o.bookmarkable) {                        var showId = this.hash.replace('#', '');                        $show.attr('id', '');                        setTimeout(function() {                            $show.attr('id', showId); // restore id                        }, 0);                    }*/                    if ($.data(this, 'href')) { // remote tab                        var a = this;                        self.load(self.$tabs.index(this) + 1, $.data(this, 'href'), function() {                            switchTab(a, $hide, $show);                        });                        if (o.cache) {                            $.removeData(this, 'href'); // if loaded once do not load them again                        }                    } else {                        switchTab(this, $hide, $show);                    }                    // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash                    /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;                    var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;                    setTimeout(function() {                        scrollTo(scrollX, scrollY);                    }, 0);*/                } else {                    throw 'jQuery UI Tabs: Mismatching fragment identifier.';                }                this.blur(); // prevent IE from keeping other link focussed when using the back button                //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE                return false;            }            // attach click event, avoid duplicates from former tabifying            this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);        },        add: function(url, text, position) {            if (url && text) {                var o = this.options;                position = position || this.$tabs.length; // append by default                if (position >= this.$tabs.length) {                    var method = 'insertAfter';                    position = this.$tabs.length;                } else {                    var method = 'insertBefore';                }                if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically                    var $container = $(url);                    // try to find an existing element before creating a new one                    ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))                        [method](this.$containers[position - 1]);                }                $('<li><a href="../../test/fro_test/scripts/plugins/' + url + '"><span>' + text + '</span></a></li>')                    [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));                this.tabify();                o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback            } else {                throw 'jQuery UI Tabs: Not enough arguments to add tab.';            }        },        remove: function(position) {            if (position && position.constructor == Number) {                var $removedTab = this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();                var $removedContainer = this.$containers.slice(position - 1, position).remove();                this.tabify();                this.options.remove($removedTab[0], $removedContainer[0]); // callback            }        },        enable: function(position) {            var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;            $li.removeClass(o.disabledClass);            if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3                $li.animate({ opacity: 1 }, 1, function() {                    $li.css({ opacity: '' });                });            }            o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback        },        disable: function(position) {            var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;            if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3                $li.animate({ opacity: 0 }, 1, function() {                   $li.css({ opacity: '' });                });            }            $li.addClass(this.options.disabledClass);            o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback        },        click: function(position) {            this.$tabs.slice(position - 1, position).trigger(this.options.event);        },        load: function(position, url, callback) {            var self = this,                o = this.options,                $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),                $span = $('span', $a),                text = $span.html();            // shift arguments            if (url && url.constructor == Function) {                callback = url;            }            // set new URL            if (url) {                $.data($a[0], 'href', url);            }            // load            if (o.spinner) {                $span.html('<em>' + o.spinner + '</em>');            }            setTimeout(function() { // timeout is again required in IE, "wait" for id being restored                $($a[0].hash).load(url, function() {                    if (o.spinner) {                        $span.html(text);                    }                    $a.removeClass(o.loadingClass);                    // This callback is required because the switch has to take place after loading                    // has completed.                    if (callback && callback.constructor == Function) {                        callback();                    }                    o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback                });            }, 0);        }    });})(jQuery);