db43c50b3bf5f0f83cf8979b77cb058d7b37f96c
[plewww.git] / planetlab / minitabs / minitabs.js
1 /*
2  
3   Animated miniTabs by frequency decoder (http://www.frequency-decoder.com/)
4  
5   Based on an idea by Rob L Glazebrook (http://www.rootarcana.com/test/smartmini/) itself
6   derived from the original idea of Stephen Clark (http://www.sgclark.com/sandbox/minislide/)
7  
8   Adjusted by Thierry Parmentelat -- INRIA - uses only forms rather than <a> tags, for supporting http-POST
9
10 */
11  
12 var miniTab = {
13  currentTab:     0,
14  activeTab:      0,
15  destX:          0,
16  destW:          0,
17  t:              0,
18  b:              0,
19  c:              0,
20  d:              20,
21  animInterval:   null,
22  sliderObj:      null,
23  aHeight:        0,
24  ul:             [],
25  liArr:          [],
26  aArr:           [],
27         
28  init: function() {
29     if(!document.getElementById || !document.getElementById("miniflex")) return;
30  
31     miniTab.ul          = document.getElementById("miniflex");
32     miniTab.liArr       = miniTab.ul.getElementsByTagName("li");
33     // Thierry: the original impl. relied on <a> links rather than forms
34     miniTab.aArr        = miniTab.ul.getElementsByTagName("input");
35  
36     for(var i = 0, li; li = miniTab.liArr[i]; i++) {
37       li.onmouseover = miniTab.aArr[i].onfocus = function(e) {
38         var pos = 0;
39         var elem = this.nodeName == "LI" ? this : this.parentNode;
40         while(elem.previousSibling) {
41           elem = elem.previousSibling;
42           if(elem.tagName && elem.tagName == "LI") pos++;
43  
44         }
45         miniTab.initSlide(pos);
46       }
47     }
48  
49     miniTab.ul.onmouseout = function(e) {
50       miniTab.initSlide(miniTab.currentTab);
51     };
52  
53     for(var i = 0, a; a = miniTab.aArr[i]; i++) {
54       if(a.className.search("active") != -1) {
55         miniTab.activeTab = miniTab.currentTab = i;
56       }
57       a.style.borderBottom  = "0px";
58       /*a.style.paddingBottom = "6px";*/
59     }
60  
61     miniTab.slideObj                = miniTab.ul.parentNode.appendChild(document.createElement("div"));
62     miniTab.slideObj.appendChild(document.createTextNode(String.fromCharCode(160)));
63     miniTab.slideObj.id             = "animated-tab";
64     miniTab.slideObj.style.top      = (miniTab.ul.offsetTop + miniTab.liArr[miniTab.activeTab].offsetTop + miniTab.aArr[miniTab.activeTab].offsetTop) + "px";
65     miniTab.slideObj.style.left     = (miniTab.ul.offsetLeft + miniTab.liArr[miniTab.activeTab].offsetLeft + miniTab.aArr[miniTab.activeTab].offsetLeft) + "px";
66     miniTab.slideObj.style.width    = miniTab.aArr[miniTab.activeTab].offsetWidth + "px";
67     miniTab.aHeight                 = miniTab.ul.offsetTop + miniTab.liArr[miniTab.activeTab].offsetTop + miniTab.aArr[miniTab.activeTab].offsetTop;
68  
69     miniTab.initSlide(miniTab.activeTab, true);
70  
71     var intervalMethod = function() { miniTab.slideIt(); }
72     miniTab.animInterval = setInterval(intervalMethod,10);
73   },
74  
75  cleanUp: function() {
76     clearInterval(miniTab.animInterval);
77     miniTab.animInterval = null;
78   },
79  
80  initSlide: function(pos, force) {
81     if(!force && pos == miniTab.activeTab) return;
82     miniTab.activeTab = pos;
83     miniTab.initAnim();
84   },
85  
86  /* search for input with type != hidden */
87  locateSubmitInput: function () {
88     inputs=miniTab.liArr[miniTab.activeTab].getElementsByTagName("input");
89     for(var i=0,input; inputs[i]; i++) {
90       input=inputs[i];
91       if (input.type == "submit") return input;
92     }
93   },
94     
95  initAnim: function() {
96     var input=miniTab.locateSubmitInput();
97     miniTab.destX = parseInt(miniTab.liArr[miniTab.activeTab].offsetLeft + input.offsetLeft + miniTab.ul.offsetLeft);
98     miniTab.destW = parseInt(input.offsetWidth);
99     miniTab.t = 0;
100     miniTab.b = miniTab.slideObj.offsetLeft;
101     miniTab.c = miniTab.destX - miniTab.b;
102  
103     miniTab.bW = miniTab.slideObj.offsetWidth;
104     miniTab.cW = miniTab.destW - miniTab.bW;
105  
106     miniTab.slideObj.style.top = (miniTab.ul.offsetTop + miniTab.liArr[miniTab.activeTab].offsetTop + miniTab.aArr[miniTab.activeTab].offsetTop) + "px";
107   },
108  
109  slideIt:function() {
110  
111     // Has the browser text size changed?
112     if(miniTab.aHeight != miniTab.ul.offsetTop + miniTab.liArr[miniTab.activeTab].offsetTop + miniTab.aArr[miniTab.activeTab].offsetTop) {
113       miniTab.initAnim();
114       miniTab.aHeight = miniTab.ul.offsetTop + miniTab.liArr[miniTab.activeTab].offsetTop + miniTab.aArr[miniTab.activeTab].offsetTop
115     };
116  
117     if(miniTab.t++ < miniTab.d) {
118       var x = miniTab.animate(miniTab.t,miniTab.b,miniTab.c,miniTab.d);
119       var w = miniTab.animate(miniTab.t,miniTab.bW,miniTab.cW,miniTab.d);
120  
121       miniTab.slideObj.style.left = parseInt(x) + "px";
122       miniTab.slideObj.style.width = parseInt(w) + "px";
123     } else {
124       miniTab.slideObj.style.left = miniTab.destX + "px";
125       miniTab.slideObj.style.width = miniTab.destW +"px";
126     }
127   },
128  
129  animate: function(t,b,c,d) {
130     if ((t/=d/2) < 1) return c/2*t*t + b;
131     return -c/2 * ((--t)*(t-2) - 1) + b;
132   }
133 }
134  
135 window.onload = miniTab.init;
136 window.onunload = miniTab.cleanUp;
137