? views_namespaced_tabs.js Index: js/base.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/js/base.js,v retrieving revision 1.10.2.2 diff -u -p -r1.10.2.2 base.js --- js/base.js 4 Dec 2009 01:08:09 -0000 1.10.2.2 +++ js/base.js 18 Dec 2009 21:49:59 -0000 @@ -11,11 +11,9 @@ Drupal.Views = {}; * jQuery UI tabs, Views integration component */ Drupal.behaviors.viewsTabs = function (context) { - if ($.ui && $.ui.tabs) { - $('#views-tabset:not(.views-processed)').addClass('views-processed').tabs({ - selectedClass: 'active' - }); - } + $('#views-tabset:not(.views-processed)').addClass('views-processed').each(function() { + new Drupal.Views.Tabs($(this), {selectedClass: 'active'}); + }); $('a.views-remove-link') .addClass('views-processed') Index: js/tabs.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/js/tabs.js,v retrieving revision 1.3.2.1 diff -u -p -r1.3.2.1 tabs.js --- js/tabs.js 2 Jun 2009 17:12:03 -0000 1.3.2.1 +++ js/tabs.js 18 Dec 2009 21:49:59 -0000 @@ -3,436 +3,400 @@ /** * @file tabs.js * jQuery UI Tabs (Tabs 3) - * + * * This is nothing more than the pure jquery UI tabs implementation. + * It has been implemented under the Drupal.Views.Tabs namespace to + * avoid conflicts with alternatve versions of jquery, jquery UI. */ -(function($) { - // if the UI scope is not availalable, add it - $.ui = $.ui || {}; +Drupal.Views = Drupal.Views || {}; - $.fn.tabs = function(initial, options) { - if (initial && initial.constructor == Object) { // shift arguments - options = initial; - initial = null; - } - options = options || {}; - - // first get initial tab from options - initial = initial && initial.constructor == Number && --initial || 0; - - return this.each(function() { - new $.ui.tabs(this, $.extend(options, { initial: initial })); - }); - }; - - // chainable tabs methods - $.each(['add', 'remove', 'enable', 'disable', 'click', 'load'], function(i, method) { - $.fn[method + 'Tab'] = function() { - var args = arguments; - return this.each(function() { - var instance = $.ui.tabs.instances[this.UI_TABS_UUID]; - instance[method].apply(instance, args); - }); - }; - }); - $.fn.selectedTab = function(returnElement) { - var selected; - if (returnElement) { - - } else { - - } - return selected; - }; - - $.ui.tabs = function(el, options) { - - this.source = el; +Drupal.Views.Tabs = function(el, options) { - this.options = $.extend({ + this.source = el; - // basic setup - initial: 0, - event: 'click', - disabled: [], - // TODO bookmarkable: $.ajaxHistory ? true : false, - unselected: false, - toggle: options.unselected ? true : false, - - // Ajax - spinner: 'Loading…', - cache: false, - hashPrefix: '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 = 'instance-' + $.ui.tabs.prototype.count++; - $.ui.tabs.instances[uuid] = this; - this.source['UI_TABS_UUID'] = uuid; - - }; - - // static - $.ui.tabs.instances = {}; - - $.extend($.ui.tabs.prototype, { - animating: false, - count: 0, - tabify: function(init) { + this.options = $.extend({ - this.$tabs = $('a:first-child', this.source); - this.$containers = $([]); + // basic setup + initial: 0, + event: 'click', + disabled: [], + // TODO bookmarkable: $.ajaxHistory ? true : false, + unselected: false, + toggle: options.unselected ? true : false, + + // Ajax + spinner: 'Loading…', + cache: false, + hashPrefix: '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 = 'instance-' + Drupal.Views.Tabs.prototype.count++; + Drupal.Views.Tabs.instances[uuid] = this; + this.source['UI_TABS_UUID'] = uuid; + +}; + +// static +Drupal.Views.Tabs.instances = {}; + +$.extend(Drupal.Views.Tabs.prototype, { + animating: false, + 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 { + var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href; + a.href = '#' + id; + a.url = url; + self.$containers = self.$containers.add( + $('#' + id)[0] || $('
') + .insertAfter( self.$containers[i - 1] || self.source ) + ); + } + }); - var self = this, o = this.options; + if (init) { + // Try to retrieve initial tab from fragment identifier in url if present, + // otherwise try to find selected class attribute on
  • . 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 { - var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href; - a.href = '#' + id; - a.url = url; - self.$containers = self.$containers.add( - $('#' + id)[0] || $('
    ') - .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
  • . - 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) ) { + 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 } - }); - - // 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 accordingly - 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); + } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) { + o.initial = i; + return false; // break } + }); - // trigger load of initial tab is remote tab - if (this.$tabs[o.initial].url) { - this.load(o.initial + 1, this.$tabs[o.initial].url); - if (o.cache) { - this.$tabs[o.initial].url = null; // if loaded once do not load them again - } - } + // 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); + }); - // disabled tabs - for (var i = 0, position; position = o.disabled[i]; i++) { - this.disable(position); + // highlight tab accordingly + 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); + } + + // trigger load of initial tab is remote tab + if (this.$tabs[o.initial].url) { + this.load(o.initial + 1, this.$tabs[o.initial].url); + if (o.cache) { + this.$tabs[o.initial].url = null; // if loaded once do not load them again } - } - // setup animations - var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed, - 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 - } + // disabled tabs + for (var i = 0, position; position = o.disabled[i]; i++) { + this.disable(position); } - // callbacks - var click = o.click, hide = o.hide, show = o.show; + } - // 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 - function hideTab(clicked, $hide, $show) { - $hide.animate(hideAnim, hideSpeed, function() { // - $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. - hide(clicked, $show, $hide[0]); - if ($show) { - showTab(clicked, $hide, $show); - } - }); + // setup animations + var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed, + 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 + } + } - // show a tab, animation prevents browser scrolling to fragment - function showTab(clicked, $hide, $show) { - // show next tab - 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) { - $hide[0].style.filter = ''; - $show[0].style.filter = ''; - } - show(clicked, $show[0], $hide[0]); - self.animating = false; - }); + // callbacks + var click = o.click, hide = o.hide, show = o.show; - } + // 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'] = ''; + } - // 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 may be closed - if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) { - if ($li.is('.' + o.selectedClass)) { - $li.removeClass(o.selectedClass); - hideTab(this, $hide); - this.blur(); - return false; - } else if (!$hide.length) { - $li.addClass(o.selectedClass); - showTab(this, $hide, $show); - this.blur(); - return false; - } + // hide a tab, animation prevents browser scrolling to fragment + function hideTab(clicked, $hide, $show) { + $hide.animate(hideAnim, hideSpeed, function() { // + $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. + hide(clicked, $show, $hide[0]); + if ($show) { + showTab(clicked, $hide, $show); } + }); + } - // If tab is already selected or disabled, animation is still running 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.disabledClass) - || self.animating || click(this, $show[0], $hide[0]) === false) { + // show a tab, animation prevents browser scrolling to fragment + function showTab(clicked, $hide, $show) { + // show next tab + 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) { + $hide[0].style.filter = ''; + $show[0].style.filter = ''; + } + show(clicked, $show[0], $hide[0]); + self.animating = false; + }); + + } + + // 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 may be closed + if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) { + if ($li.is('.' + o.selectedClass)) { + $li.removeClass(o.selectedClass); + hideTab(this, $hide); + this.blur(); + return false; + } else if (!$hide.length) { + $li.addClass(o.selectedClass); + showTab(this, $hide, $show); this.blur(); return false; } + } - self.animating = true; + // If tab is already selected or disabled, animation is still running 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.disabledClass) + || self.animating || click(this, $show[0], $hide[0]) === false) { + this.blur(); + return false; + } - // show new tab - if ($show.length) { + self.animating = true; - // 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 (this.url) { // remote tab - var a = this; - self.load(self.$tabs.index(this) + 1, this.url, function() { - switchTab(a, $hide, $show); - }); - if (o.cache) { - this.url = null; // if loaded once do not load them again - } - } else { - switchTab(this, $hide, $show); - } + // show new tab + if ($show.length) { - // 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; + // 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() { - scrollTo(scrollX, scrollY); - }, 0);*/ + $show.attr('id', showId); // restore id + }, 0); + }*/ + if (this.url) { // remote tab + var a = this; + self.load(self.$tabs.index(this) + 1, this.url, function() { + switchTab(a, $hide, $show); + }); + if (o.cache) { + this.url = null; // if loaded once do not load them again + } } else { - throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.'); + switchTab(this, $hide, $show); } - 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; + // 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 Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.'); } - // attach click event, avoid duplicates from former tabifying - this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick); + this.blur(); // prevent IE from keeping other link focussed when using the back button - }, - 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 || $('
    ')) - [method](this.$containers[position - 1]); - } - $('
  • ' + text + '
  • ') - [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)')); - this.tabify(); - o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback + //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 { - throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.'); + var method = 'insertBefore'; } - }, - remove: function(position) { - if (position && position.constructor == Number) { - this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove(); - this.$containers.slice(position - 1, position).remove(); - this.tabify(); - } - this.options.remove(); // 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() { + 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 || $('
    ')) + [method](this.$containers[position - 1]); + } + $('
  • ' + text + '
  • ') + [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 Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.'); + } + }, + remove: function(position) { + if (position && position.constructor == Number) { + this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove(); + this.$containers.slice(position - 1, position).remove(); + this.tabify(); + } + this.options.remove(); // 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: '' }); - }); - } - 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('click'); - }, - 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) { - $a[0].url = url; - } - - // load - if (o.spinner) { - $span.html('' + o.spinner + ''); - } - 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 needed 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); + }); + } + $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('click'); + }, + 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; } - }); -})(jQuery); + + // set new URL + if (url) { + $a[0].url = url; + } + + // load + if (o.spinner) { + $span.html('' + o.spinner + ''); + } + 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 needed 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); + } +});