summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEarl Miles2010-03-10 20:08:58 (GMT)
committer Earl Miles2010-03-10 20:08:58 (GMT)
commit9b9b27a7152e968a7e46615e9c7434f7b3f1dceb (patch)
treeb5d0e7ba62cc207f8be30a936669ce1480078132
parent0a27a14867e0c36303ce21cc2758083e4585edf4 (diff)
#621980 by yhahn: Namespace tabs.js to guarantee no conflicts with jQuery UI.
-rw-r--r--CHANGELOG.txt1
-rw-r--r--js/ajax.js11
-rw-r--r--js/base.js8
-rw-r--r--js/tabs.js734
4 files changed, 358 insertions, 396 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 281b08e..bf9a6f8 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -27,6 +27,7 @@ Views 2.x-dev
o #713210 by dereine: Node language settings could persist for subsequent rows if they should not have had a language.
o #674772 by joachim: Unable to distinguish profile.module fields with same name in different profile categories.
o #727798 by SteveReher: Fix typo in overrides.html documentation.
+ o #621980 by yhahn: Namespace tabs.js to guarantee no conflicts with jQuery UI.
Other changes:
o #570558 by yhahn: Segment default views caching to conserve memory used by Views during normal operation.
diff --git a/js/ajax.js b/js/ajax.js
index 9831803..a418d1e 100644
--- a/js/ajax.js
+++ b/js/ajax.js
@@ -109,15 +109,14 @@ Drupal.Views.Ajax.ajaxResponse = function(data) {
// Go through and add any requested tabs
if (data.tab) {
for (id in data.tab) {
- $('#views-tabset').addTab(id, data.tab[id]['title'], 0);
+ // Retrieve the tabset instance by stored ID.
+ var instance = Drupal.Views.Tabs.instances[$('#views-tabset').data('UI_TABS_UUID')];
+ instance.add(id, data.tab[id]['title'], 0);
+ instance.click(instance.$tabs.length);
+
$(id).html(data.tab[id]['body']);
$(id).addClass('views-tab');
Drupal.attachBehaviors(id);
-
- // This is kind of annoying, but we have to actually to find where the new
- // tab is.
- var instance = $.ui.tabs.instances[$('#views-tabset').get(0).UI_TABS_UUID];
- $('#views-tabset').clickTab(instance.$tabs.length);
}
}
diff --git a/js/base.js b/js/base.js
index 2b7f32c..e2ddc0f 100644
--- a/js/base.js
+++ b/js/base.js
@@ -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')
diff --git a/js/tabs.js b/js/tabs.js
index a66a280..f5d5ea0 100644
--- a/js/tabs.js
+++ b/js/tabs.js
@@ -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 || {};
-
- $.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 }));
+Drupal.Views = Drupal.Views || {};
+
+Drupal.Views.Tabs = function(el, options) {
+
+ this.source = el;
+
+ this.options = $.extend({
+
+ // 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.data('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] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
+ .insertAfter( self.$containers[i - 1] || self.source )
+ );
+ }
});
- };
-
- // 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;
-
- this.options = $.extend({
-
- // basic setup
- initial: 0,
- event: 'click',
- disabled: [],
- // TODO bookmarkable: $.ajaxHistory ? true : false,
- unselected: false,
- toggle: options.unselected ? true : false,
-
- // Ajax
- spinner: 'Loading&#8230;',
- 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.$tabs = $('a:first-child', this.source);
- this.$containers = $([]);
-
- 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 <li>.
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] || $('<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) ) {
+ 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);
- }
-
- // 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
- }
+ } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
+ o.initial = i;
+ return false; // break
}
+ });
- // disabled tabs
- for (var i = 0, position; position = o.disabled[i]; i++) {
- this.disable(position);
- }
+ // 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);
}
- // 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
+ // 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
}
}
- // 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'] = '';
+ // disabled tabs
+ for (var i = 0, position; position = o.disabled[i]; i++) {
+ this.disable(position);
}
- // 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
+ // 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);
}
- $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;
- });
+ });
+ }
+ // 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;
- }
- }
+ // 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);
+ }
- // 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) {
+ // 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;
-
- // 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 (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);
- }
+ // 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;
+ }
- // 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;
+ self.animating = true;
+
+ // 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() {
- 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);
-
- },
- 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="' + 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
+ 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 {
- 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();
+ 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]);
}
- 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><a href="' + 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 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;
- }
+ });
+ }
+ $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;
- }
+ // set new URL
+ if (url) {
+ $a[0].url = 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 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);
+ // load
+ if (o.spinner) {
+ $span.html('<em>' + o.spinner + '</em>');
}
- });
-})(jQuery);
+ 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);
+ }
+});