/[drupal]/contributions/modules/views/js/tabs.js
ViewVC logotype

Contents of /contributions/modules/views/js/tabs.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download) (as text)
Tue Jun 2 17:12:13 2009 UTC (5 months, 3 weeks ago) by merlinofchaos
Branch: MAIN
CVS Tags: DRUPAL-6--2-7, DRUPAL-6--2-6, HEAD
Branch point for: DRUPAL-6--2, DRUPAL-7--3
Changes since 1.3: +49 -49 lines
File MIME type: text/javascript
#428202 by dereine: Cleanup whitespace in javascript files.
1 // $Id: tabs.js,v 1.3 2008/03/30 15:58:26 merlinofchaos Exp $
2
3 /**
4 * @file tabs.js
5 * jQuery UI Tabs (Tabs 3)
6 *
7 * This is nothing more than the pure jquery UI tabs implementation.
8 */
9 (function($) {
10
11 // if the UI scope is not availalable, add it
12 $.ui = $.ui || {};
13
14 $.fn.tabs = function(initial, options) {
15 if (initial && initial.constructor == Object) { // shift arguments
16 options = initial;
17 initial = null;
18 }
19 options = options || {};
20
21 // first get initial tab from options
22 initial = initial && initial.constructor == Number && --initial || 0;
23
24 return this.each(function() {
25 new $.ui.tabs(this, $.extend(options, { initial: initial }));
26 });
27 };
28
29 // chainable tabs methods
30 $.each(['add', 'remove', 'enable', 'disable', 'click', 'load'], function(i, method) {
31 $.fn[method + 'Tab'] = function() {
32 var args = arguments;
33 return this.each(function() {
34 var instance = $.ui.tabs.instances[this.UI_TABS_UUID];
35 instance[method].apply(instance, args);
36 });
37 };
38 });
39 $.fn.selectedTab = function(returnElement) {
40 var selected;
41 if (returnElement) {
42
43 } else {
44
45 }
46 return selected;
47 };
48
49 $.ui.tabs = function(el, options) {
50
51 this.source = el;
52
53 this.options = $.extend({
54
55 // basic setup
56 initial: 0,
57 event: 'click',
58 disabled: [],
59 // TODO bookmarkable: $.ajaxHistory ? true : false,
60 unselected: false,
61 toggle: options.unselected ? true : false,
62
63 // Ajax
64 spinner: 'Loading…',
65 cache: false,
66 hashPrefix: 'tab-',
67
68 // animations
69 /*fxFade: null,
70 fxSlide: null,
71 fxShow: null,
72 fxHide: null,*/
73 fxSpeed: 'normal',
74 /*fxShowSpeed: null,
75 fxHideSpeed: null,*/
76
77 // callbacks
78 add: function() {},
79 remove: function() {},
80 enable: function() {},
81 disable: function() {},
82 click: function() {},
83 hide: function() {},
84 show: function() {},
85 load: function() {},
86
87 // CSS classes
88 navClass: 'ui-tabs-nav',
89 selectedClass: 'ui-tabs-selected',
90 disabledClass: 'ui-tabs-disabled',
91 containerClass: 'ui-tabs-container',
92 hideClass: 'ui-tabs-hide',
93 loadingClass: 'ui-tabs-loading'
94
95 }, options);
96
97 this.tabify(true);
98
99 // save instance for later
100 var uuid = 'instance-' + $.ui.tabs.prototype.count++;
101 $.ui.tabs.instances[uuid] = this;
102 this.source['UI_TABS_UUID'] = uuid;
103
104 };
105
106 // static
107 $.ui.tabs.instances = {};
108
109 $.extend($.ui.tabs.prototype, {
110 animating: false,
111 count: 0,
112 tabify: function(init) {
113
114 this.$tabs = $('a:first-child', this.source);
115 this.$containers = $([]);
116
117 var self = this, o = this.options;
118
119 this.$tabs.each(function(i, a) {
120 // inline tab
121 if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash
122 self.$containers = self.$containers.add(a.hash);
123 }
124 // remote tab
125 else {
126 var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href;
127 a.href = '#' + id;
128 a.url = url;
129 self.$containers = self.$containers.add(
130 $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
131 .insertAfter( self.$containers[i - 1] || self.source )
132 );
133 }
134 });
135
136 if (init) {
137
138 // Try to retrieve initial tab from fragment identifier in url if present,
139 // otherwise try to find selected class attribute on <li>.
140 this.$tabs.each(function(i, a) {
141 if (location.hash) {
142 if (a.hash == location.hash) {
143 o.initial = i;
144 // prevent page scroll to fragment
145 //if (($.browser.msie || $.browser.opera) && !o.remote) {
146 if ($.browser.msie || $.browser.opera) {
147 var $toShow = $(location.hash), toShowId = $toShow.attr('id');
148 $toShow.attr('id', '');
149 setTimeout(function() {
150 $toShow.attr('id', toShowId); // restore id
151 }, 500);
152 }
153 scrollTo(0, 0);
154 return false; // break
155 }
156 } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
157 o.initial = i;
158 return false; // break
159 }
160 });
161
162 // attach necessary classes for styling if not present
163 $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);
164 this.$containers.each(function() {
165 var $this = $(this);
166 $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);
167 });
168
169 // highlight tab accordingly
170 var $lis = $('li', this.source);
171 this.$containers.addClass(o.hideClass);
172 $lis.removeClass(o.selectedClass);
173 if (!o.unselected) {
174 this.$containers.slice(o.initial, o.initial + 1).show();
175 $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);
176 }
177
178 // trigger load of initial tab is remote tab
179 if (this.$tabs[o.initial].url) {
180 this.load(o.initial + 1, this.$tabs[o.initial].url);
181 if (o.cache) {
182 this.$tabs[o.initial].url = null; // if loaded once do not load them again
183 }
184 }
185
186 // disabled tabs
187 for (var i = 0, position; position = o.disabled[i]; i++) {
188 this.disable(position);
189 }
190
191 }
192
193 // setup animations
194 var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,
195 hideSpeed = o.fxHideSpeed || o.fxSpeed;
196 if (o.fxSlide || o.fxFade) {
197 if (o.fxSlide) {
198 showAnim['height'] = 'show';
199 hideAnim['height'] = 'hide';
200 }
201 if (o.fxFade) {
202 showAnim['opacity'] = 'show';
203 hideAnim['opacity'] = 'hide';
204 }
205 } else {
206 if (o.fxShow) {
207 showAnim = o.fxShow;
208 } else { // use some kind of animation to prevent browser scrolling to the tab
209 showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
210 showSpeed = 1; // as little as 1 is sufficient
211 }
212 if (o.fxHide) {
213 hideAnim = o.fxHide;
214 } else { // use some kind of animation to prevent browser scrolling to the tab
215 hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
216 hideSpeed = 1; // as little as 1 is sufficient
217 }
218 }
219
220 // callbacks
221 var click = o.click, hide = o.hide, show = o.show;
222
223 // reset some styles to maintain print style sheets etc.
224 var resetCSS = { display: '', overflow: '', height: '' };
225 if (!$.browser.msie) { // not in IE to prevent ClearType font issue
226 resetCSS['opacity'] = '';
227 }
228
229 // hide a tab, animation prevents browser scrolling to fragment
230 function hideTab(clicked, $hide, $show) {
231 $hide.animate(hideAnim, hideSpeed, function() { //
232 $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
233 hide(clicked, $show, $hide[0]);
234 if ($show) {
235 showTab(clicked, $hide, $show);
236 }
237 });
238 }
239
240 // show a tab, animation prevents browser scrolling to fragment
241 function showTab(clicked, $hide, $show) {
242 // show next tab
243 if (!(o.fxSlide || o.fxFade || o.fxShow)) {
244 $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers
245 }
246 $show.animate(showAnim, showSpeed, function() {
247 $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
248 if ($.browser.msie) {
249 $hide[0].style.filter = '';
250 $show[0].style.filter = '';
251 }
252 show(clicked, $show[0], $hide[0]);
253 self.animating = false;
254 });
255
256 }
257
258 // switch a tab
259 function switchTab(clicked, $hide, $show) {
260 /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
261 $.ajaxHistory.update(clicked.hash);
262 }*/
263 $(clicked).parents('li:eq(0)').addClass(o.selectedClass)
264 .siblings().removeClass(o.selectedClass);
265 hideTab(clicked, $hide, $show);
266 }
267
268 // tab click handler
269 function tabClick(e) {
270
271 //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
272 var $li = $(this).parents('li:eq(0)'), $hide = self.$containers.filter(':visible'), $show = $(this.hash);
273
274 // if tab may be closed
275 if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) {
276 if ($li.is('.' + o.selectedClass)) {
277 $li.removeClass(o.selectedClass);
278 hideTab(this, $hide);
279 this.blur();
280 return false;
281 } else if (!$hide.length) {
282 $li.addClass(o.selectedClass);
283 showTab(this, $hide, $show);
284 this.blur();
285 return false;
286 }
287 }
288
289 // If tab is already selected or disabled, animation is still running or click callback
290 // returns false stop here.
291 // Check if click handler returns false last so that it is not executed for a disabled tab!
292 if ($li.is('.' + o.selectedClass + ', .' + o.disabledClass)
293 || self.animating || click(this, $show[0], $hide[0]) === false) {
294 this.blur();
295 return false;
296 }
297
298 self.animating = true;
299
300 // show new tab
301 if ($show.length) {
302
303 // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
304 /*if ($.browser.msie && o.bookmarkable) {
305 var showId = this.hash.replace('#', '');
306 $show.attr('id', '');
307 setTimeout(function() {
308 $show.attr('id', showId); // restore id
309 }, 0);
310 }*/
311
312 if (this.url) { // remote tab
313 var a = this;
314 self.load(self.$tabs.index(this) + 1, this.url, function() {
315 switchTab(a, $hide, $show);
316 });
317 if (o.cache) {
318 this.url = null; // if loaded once do not load them again
319 }
320 } else {
321 switchTab(this, $hide, $show);
322 }
323
324 // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
325 /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
326 var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
327 setTimeout(function() {
328 scrollTo(scrollX, scrollY);
329 }, 0);*/
330
331 } else {
332 throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.');
333 }
334
335 this.blur(); // prevent IE from keeping other link focussed when using the back button
336
337 //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
338 return false;
339
340 }
341
342 // attach click event, avoid duplicates from former tabifying
343 this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);
344
345 },
346 add: function(url, text, position) {
347 if (url && text) {
348 var o = this.options;
349 position = position || this.$tabs.length; // append by default
350 if (position >= this.$tabs.length) {
351 var method = 'insertAfter';
352 position = this.$tabs.length;
353 } else {
354 var method = 'insertBefore';
355 }
356 if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically
357 var $container = $(url);
358 // try to find an existing element before creating a new one
359 ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))
360 [method](this.$containers[position - 1]);
361 }
362 $('<li><a href="' + url + '"><span>' + text + '</span></a></li>')
363 [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));
364 this.tabify();
365 o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback
366 } else {
367 throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.');
368 }
369 },
370 remove: function(position) {
371 if (position && position.constructor == Number) {
372 this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();
373 this.$containers.slice(position - 1, position).remove();
374 this.tabify();
375 }
376 this.options.remove(); // callback
377 },
378 enable: function(position) {
379 var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
380 $li.removeClass(o.disabledClass);
381 if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3
382 $li.animate({ opacity: 1 }, 1, function() {
383 $li.css({ opacity: '' });
384 });
385 }
386 o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
387 },
388 disable: function(position) {
389 var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
390 if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3
391 $li.animate({ opacity: 0 }, 1, function() {
392 $li.css({ opacity: '' });
393 });
394 }
395 $li.addClass(this.options.disabledClass);
396 o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
397 },
398 click: function(position) {
399 this.$tabs.slice(position - 1, position).trigger('click');
400 },
401 load: function(position, url, callback) {
402 var self = this,
403 o = this.options,
404 $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),
405 $span = $('span', $a),
406 text = $span.html();
407
408 // shift arguments
409 if (url && url.constructor == Function) {
410 callback = url;
411 }
412
413 // set new URL
414 if (url) {
415 $a[0].url = url;
416 }
417
418 // load
419 if (o.spinner) {
420 $span.html('<em>' + o.spinner + '</em>');
421 }
422 setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
423 $($a[0].hash).load(url, function() {
424 if (o.spinner) {
425 $span.html(text);
426 }
427 $a.removeClass(o.loadingClass);
428 // This callback is needed because the switch has to take place after loading
429 // has completed.
430 if (callback && callback.constructor == Function) {
431 callback();
432 }
433 o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback
434 });
435 }, 0);
436 }
437 });
438 })(jQuery);

  ViewVC Help
Powered by ViewVC 1.1.2