lib-jquery-style-custom-development-bundle-ui-ui.tabs.js / js
/* * jQuery UI Tabs 1.7.1 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Tabs * * Depends: * ui.core.js */ (function(.widget("ui.tabs", { _init: function() { if (this.options.deselectable !== undefined) { this.options.collapsible = this.options.deselectable; } this._tabify(true); }, _setData: function(key, value) { if (key == 'selected') { if (this.options.collapsible && value == this.options.selected) { return; } this.select(value); } else { this.options[key] = value; if (key == 'deselectable') { this.options.collapsible = value; } this._tabify(); } }, _tabId: function(a) { return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') || this.options.idPrefix + // we need this because an id may contain a ":" }, _cookie: function() { var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + .data(this.list[0])); return .makeArray(arguments))); }, _ui: function(tab, panel) { return { tab: tab, panel: panel, index: this.anchors.index(tab) }; }, _cleanup: function() { // restore all former loading tabs labels this.lis.filter('.ui-state-processing').removeClass('ui-state-processing') .find('span:data(label.tabs)') .each(function() { var el = this; el.html(el.data('label.tabs')).removeData('label.tabs'); }); }, _tabify: function(init) { this.list = this.element.children('ul:first'); this.lis = $('li:has(a[href])', this.list); this.anchors = this.lis.map(function() { return $('a', this)[0]; }); this.panels = $([]); var self = this, o = this.options; var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash this.anchors.each(function(i, a) { var href = a.attr('href'); // For dynamically created HTML that contains a hash as href IE < 8 expands // such href to the full page url with hash and then misinterprets tab as ajax. // Same consideration applies for an added tab with a fragment identifier // since a[href=#fragment-identifier] does unexpectedly not match. // Thus normalize href attribute... var hrefBase = href.split('#')[0], baseEl; if (hrefBase && (hrefBase === location.toString().split('#')[0] || (baseEl = $('base')[0]) && hrefBase === baseEl.href)) { href = a.hash; a.href = href; } // inline tab if (fragmentId.test(href)) { self.panels = self.panels.add(self._sanitizeSelector(href)); } // remote tab else if (href != '#') { // prevent loading the page itself if href is just "#" .data(a, 'load.tabs', href.replace(/#.*panel = $('#' + id); if (!panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom') .insertAfter(self.panels[i - 1] || self.list); panel); } // invalid tab href else { o.disabled.push(i); } }); // initialization from scratch if (init) { // attach necessary classes for styling this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all'); this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'); this.lis.addClass('ui-state-default ui-corner-top'); this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom'); // Selected tab // use "selected" option or try to retrieve: // 1. from fragment identifier in url // 2. from cookie // 3. from selected class attribute on <li> if (o.selected === undefined) { if (location.hash) { this.anchors.each(function(i, a) { if (a.hash == location.hash) { o.selected = i; return false; // break } }); } if (typeof o.selected != 'number' && o.cookie) { o.selected = parseInt(self._cookie(), 10); } if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) { o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); } o.selected = o.selected || 0; } else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release o.selected = -1; } // sanity check - default to first tab... o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0; // Take disabling tabs via class attribute from HTML // into account and update option properly. // A selected tab cannot become disabled. o.disabled = .map(this.lis.filter('.ui-state-disabled'), function(n, i) { return self.lis.index(n); } ) )).sort(); if (.inArray(o.selected, o.disabled), 1); } // highlight selected tab this.panels.addClass('ui-tabs-hide'); this.lis.removeClass('ui-tabs-selected ui-state-active'); if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list this.panels.eq(o.selected).removeClass('ui-tabs-hide'); this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active'); // seems to be expected behavior that the show callback is fired self.element.queue("tabs", function() { self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected])); }); this.load(o.selected); } // clean up to avoid memory leaks in certain versions of IE 6 window.bind('unload', function() { self.lis.add(self.anchors).unbind('.tabs'); self.lis = self.anchors = self.panels = null; }); } // update selected after add/remove else { o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); } // update collapsible this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible'); // set or update cookie after init and add/remove respectively if (o.cookie) { this._cookie(o.selected, o.cookie); } // disable tabs for (var i = 0, li; (li = this.lis[i]); i++) { li[}; var removeState = function(state, el) { el.removeClass('ui-state-' + state); }; this.lis.bind('mouseover.tabs', function() { addState('hover', this); }); this.lis.bind('mouseout.tabs', function() { removeState('hover', this); }); this.anchors.bind('focus.tabs', function() { addState('focus', this.closest('li')); }); this.anchors.bind('blur.tabs', function() { removeState('focus', this.closest('li')); }); } // set up animations var hideFx, showFx; if (o.fx) { if (.isArray(o.fx)) { hideFx = o.fx[0]; showFx = o.fx[1]; } else { hideFx = showFx = o.fx; } } // Reset certain styles left over from animation // and prevent IE's ClearType bug... function resetStyle(el.css({ display: '' }); if (el[0].style.removeAttribute('filter'); } } // Show a tab... var showTab = showFx ? function(clicked, show.hide().removeClass('ui-tabs-hide') // avoid flicker that way .animate(showFx, showFx.duration || 'normal', function() { resetStyle(show[0])); }); } : function(clicked, show.removeClass('ui-tabs-hide'); self._trigger('show', null, self._ui(clicked, }; // Hide a tab, show is optional... var hideTab = hideFx ? function(clicked, hide.animate(hideFx, hideFx.duration || 'normal', function() { self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); hide, hideFx); self.element.dequeue("tabs"); }); } : function(clicked, show) { self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); }; // attach tab event handler, unbind to avoid duplicates from former tabifying... this.anchors.bind(o.event + '.tabs', function() { var el = this, li = this.closest('li'), show = $(self._sanitizeSelector(this.hash)); // If tab is already selected and not collapsible or tab disabled or // or is already loading or click callback returns false stop here. // Check if click handler returns false last so that it is not executed // for a disabled or loading tab! if ((li.hasClass('ui-state-disabled') || show[0])) === false) { this.blur(); return false; } o.selected = self.anchors.index(this); self.abort(); // if tab may be closed if (o.collapsible) { if (hide); }).dequeue("tabs"); this.blur(); return false; } else if (!show); }); self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 this.blur(); return false; } } if (o.cookie) { self._cookie(o.selected, o.cookie); } // show new tab if (hide.length) { self.element.queue("tabs", function() { hideTab(el, show); }); self.load(self.anchors.index(this)); } else { throw 'jQuery UI Tabs: Mismatching fragment identifier.'; } // Prevent IE from keeping other link focussed when using the back button // and remove dotted border from clicked link. This is controlled via CSS // in modern browsers; blur() removes focus from address bar in Firefox // which can become a usability and annoying problem with tabs('rotate'). if (.data(this, 'href.tabs'); if (href) { this.href = href; } var .each(['href', 'load', 'cache'], function(i, prefix) { .data(this, 'destroy.tabs')) { this.remove(); } else { this.removeClass([ 'ui-state-default', 'ui-corner-top', 'ui-tabs-selected', 'ui-state-active', 'ui-state-hover', 'ui-state-focus', 'ui-state-disabled', 'ui-tabs-panel', 'ui-widget-content', 'ui-corner-bottom', 'ui-tabs-hide' ].join(' ')); } }); if (o.cookie) { this._cookie(null, o.cookie); } }, add: function(url, label, index) { if (index === undefined) { index = this.anchors.length; // append by default } var self = this, o = this.options, li)[0]); panel = $('#' + id); if (!panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true); } li.appendTo(this.list); li.insertBefore(this.lis[index]); .map(o.disabled, function(n, i) { return n >= index ? ++n : n; }); this._tabify(); if (this.anchors.length == 1) { // after tabify panel.removeClass('ui-tabs-hide'); this.element.queue("tabs", function() { self._trigger('show', null, self._ui(self.anchors[0], self.panels[0])); }); this.load(0); } // callback this._trigger('add', null, this._ui(this.anchors[index], this.panels[index])); }, remove: function(index) { var o = this.options, panel = this.panels.eq(index).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. if (.map(li.find('a')[0], .inArray(index, o.disabled) == -1) { return; } this.lis.eq(index).removeClass('ui-state-disabled'); o.disabled = =' + index + ']')); } else if (index === null) { // usage of null is deprecated, TODO remove in next release index = -1; } if (index == -1 && this.options.collapsible) { index = this.options.selected; } this.anchors.eq(index).trigger(this.options.event + '.tabs'); }, load: function(index) { var self = this, o = this.options, a = this.anchors.eq(index)[0], url = .data(a, 'cache.tabs')) { this.element.dequeue("tabs"); return; } // load remote from here on this.lis.eq(index).addClass('ui-state-processing'); if (o.spinner) { var span = $('span', a); span.data('label.tabs', span.html()).html(o.spinner); } this.xhr = .extend({}, o.ajaxOptions, { url: url, success: function(r, s) { $(self._sanitizeSelector(a.hash)).html(r); // take care of tab labels self._cleanup(); if (o.cache) { .extend(<div></div>', spinner: '<em>Loading…</em>', tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' } }); /* * Tabs Extensions */ /* * Rotate */ .extend(// in case of a true click self.rotate(null); } } : function(e) { t = o.selected; rotate(); }); // start rotation if (ms) { this.element.bind('tabsshow', rotate); this.anchors.bind(o.event + '.tabs', stop); rotate(); } // stop rotation else { clearTimeout(self.rotation); this.element.unbind('tabsshow', rotate); this.anchors.unbind(o.event + '.tabs', stop); delete this._rotate; delete this._unrotate; } } }); })(jQuery);
(C) Æliens 20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.