Index: trunk/extensions/Tabber/Tabber.php |
— | — | @@ -0,0 +1,55 @@ |
| 2 | +<?php |
| 3 | +# Credits |
| 4 | +$wgExtensionCredits['parserhook'][] = array( |
| 5 | + 'name'=>'Tabber', |
| 6 | + 'author'=>'Eric Fortin', |
| 7 | + 'url'=>'http://www.mediawiki.org/wiki/Extension:Tabber', |
| 8 | + 'description'=>'Create tabs that contain wiki compatible based data', |
| 9 | + 'version'=>'1.2' |
| 10 | +); |
| 11 | + |
| 12 | +$wgExtensionFunctions[] = "wfTabber"; |
| 13 | + |
| 14 | +// function adds the wiki extension |
| 15 | +function wfTabber() { |
| 16 | + global $wgParser; |
| 17 | + $wgParser->setHook( "tabber", "renderTabber" ); |
| 18 | +} |
| 19 | + |
| 20 | +function renderTabber( $paramstring, $params = array() ){ |
| 21 | + global $wgParser, $wgScriptPath; |
| 22 | + $wgParser->disableCache(); |
| 23 | + |
| 24 | + $path = $wgScriptPath . '/extensions/Tabber/'; |
| 25 | + |
| 26 | + $htmlHeader = '<script type="text/javascript" src="'.$path.'Tabber.js"></script>' |
| 27 | + . '<link rel="stylesheet" href="'.$path.'Tabber.css" TYPE="text/css" MEDIA="screen">' |
| 28 | + . '<div class="tabber">'; |
| 29 | + |
| 30 | + $htmlFooter = '</div>'; |
| 31 | + |
| 32 | + $htmlTabs = ''; |
| 33 | + |
| 34 | + $arr = explode("|-|", $paramstring); |
| 35 | + foreach($arr as $tab){ |
| 36 | + $htmlTabs .= buildTab($tab); |
| 37 | + } |
| 38 | + |
| 39 | + return $htmlHeader . $htmlTabs . $htmlFooter; |
| 40 | +} |
| 41 | + |
| 42 | +function buildTab($tab){ |
| 43 | + global $wgParser; |
| 44 | + |
| 45 | + if( trim($tab) == '' ) return ''; |
| 46 | + |
| 47 | + $arr = preg_split("/=/",$tab); |
| 48 | + $tabName = array_shift( $arr ); |
| 49 | + $tabBody = $wgParser->recursiveTagParse( implode("=",$arr) ); |
| 50 | + |
| 51 | + $tab = '<div class="tabbertab" title="'.htmlspecialchars($tabName).'">' |
| 52 | + . '<p>'.$tabBody.'</p>' |
| 53 | + . '</div>'; |
| 54 | + |
| 55 | + return $tab; |
| 56 | +} |
Property changes on: trunk/extensions/Tabber/Tabber.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 57 | + native |
Index: trunk/extensions/Tabber/Tabber.css |
— | — | @@ -0,0 +1,112 @@ |
| 2 | +/*Copied from http://www.barelyfitz.com/projects/tabber/example.css used under mit license |
| 3 | +see http://www.barelyfitz.com/projects/tabber/ |
| 4 | +*/ |
| 5 | +/* $Id: example.css,v 1.5 2006/03/27 02:44:36 pat Exp $ */ |
| 6 | + |
| 7 | +/*-------------------------------------------------- |
| 8 | + REQUIRED to hide the non-active tab content. |
| 9 | + But do not hide them in the print stylesheet! |
| 10 | + --------------------------------------------------*/ |
| 11 | +.tabberlive .tabbertabhide { |
| 12 | + display:none; |
| 13 | +} |
| 14 | + |
| 15 | +/*-------------------------------------------------- |
| 16 | + .tabber = before the tabber interface is set up |
| 17 | + .tabberlive = after the tabber interface is set up |
| 18 | + --------------------------------------------------*/ |
| 19 | +.tabber { |
| 20 | +} |
| 21 | +.tabberlive { |
| 22 | + margin-top:1em; |
| 23 | +} |
| 24 | + |
| 25 | +/*-------------------------------------------------- |
| 26 | + ul.tabbernav = the tab navigation list |
| 27 | + li.tabberactive = the active tab |
| 28 | + --------------------------------------------------*/ |
| 29 | +ul.tabbernav |
| 30 | +{ |
| 31 | + margin:0; |
| 32 | + padding: 3px 0; |
| 33 | + border-bottom: 1px solid #CCC; |
| 34 | + font: bold 12px Verdana, sans-serif; |
| 35 | +} |
| 36 | + |
| 37 | +ul.tabbernav li |
| 38 | +{ |
| 39 | + list-style: none; |
| 40 | + margin: 0; |
| 41 | + display: inline; |
| 42 | +} |
| 43 | + |
| 44 | +ul.tabbernav li a |
| 45 | +{ |
| 46 | + padding: 3px 0.5em; |
| 47 | + margin-left: 3px; |
| 48 | + border: 1px solid #ccc; |
| 49 | + border-bottom: none; |
| 50 | + background: #f2f7ff; |
| 51 | + text-decoration: none; |
| 52 | +} |
| 53 | + |
| 54 | +ul.tabbernav li a:link { color: #448; } |
| 55 | +ul.tabbernav li a:visited { color: #667; } |
| 56 | + |
| 57 | +ul.tabbernav li a:hover |
| 58 | +{ |
| 59 | + color: #000; |
| 60 | + background: #fff9f2; |
| 61 | + border-color: #CCC; |
| 62 | +} |
| 63 | + |
| 64 | +ul.tabbernav li.tabberactive a |
| 65 | +{ |
| 66 | + background-color: #fff; |
| 67 | + border-bottom: 1px solid #fff; |
| 68 | +} |
| 69 | + |
| 70 | +ul.tabbernav li.tabberactive a:hover |
| 71 | +{ |
| 72 | + color: #000; |
| 73 | + background: white; |
| 74 | + border-bottom: 1px solid white; |
| 75 | +} |
| 76 | + |
| 77 | +/*-------------------------------------------------- |
| 78 | + .tabbertab = the tab content |
| 79 | + Add style only after the tabber interface is set up (.tabberlive) |
| 80 | + --------------------------------------------------*/ |
| 81 | +.tabberlive .tabbertab { |
| 82 | + padding:5px; |
| 83 | + border:1px solid #CCC; |
| 84 | + border-top:0; |
| 85 | + |
| 86 | + /* If you don't want the tab size changing whenever a tab is changed |
| 87 | + you can set a fixed height */ |
| 88 | + |
| 89 | + /* height:200px; */ |
| 90 | + |
| 91 | + /* If you set a fix height set overflow to auto and you will get a |
| 92 | + scrollbar when necessary */ |
| 93 | + |
| 94 | + /* overflow:auto; */ |
| 95 | +} |
| 96 | + |
| 97 | +/* If desired, hide the heading since a heading is provided by the tab */ |
| 98 | +.tabberlive .tabbertab h2 { |
| 99 | + display:none; |
| 100 | +} |
| 101 | +.tabberlive .tabbertab h3 { |
| 102 | + display:none; |
| 103 | +} |
| 104 | + |
| 105 | +/* Example of using an ID to set different styles for the tabs on the page */ |
| 106 | +.tabberlive#tab1 { |
| 107 | +} |
| 108 | +.tabberlive#tab2 { |
| 109 | +} |
| 110 | +.tabberlive#tab2 .tabbertab { |
| 111 | + height:200px; |
| 112 | + overflow:auto; |
| 113 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/Tabber/Tabber.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 114 | + native |
Index: trunk/extensions/Tabber/Tabber.js |
— | — | @@ -0,0 +1,523 @@ |
| 2 | +/*================================================== |
| 3 | + $Id: tabber.js,v 1.9 2006/04/27 20:51:51 pat Exp $ |
| 4 | + tabber.js by Patrick Fitzgerald pat@barelyfitz.com |
| 5 | + |
| 6 | + Documentation can be found at the following URL: |
| 7 | + http://www.barelyfitz.com/projects/tabber/ |
| 8 | + |
| 9 | + License (http://www.opensource.org/licenses/mit-license.php) |
| 10 | + |
| 11 | + Copyright (c) 2006 Patrick Fitzgerald |
| 12 | + |
| 13 | + Permission is hereby granted, free of charge, to any person |
| 14 | + obtaining a copy of this software and associated documentation files |
| 15 | + (the "Software"), to deal in the Software without restriction, |
| 16 | + including without limitation the rights to use, copy, modify, merge, |
| 17 | + publish, distribute, sublicense, and/or sell copies of the Software, |
| 18 | + and to permit persons to whom the Software is furnished to do so, |
| 19 | + subject to the following conditions: |
| 20 | + |
| 21 | + The above copyright notice and this permission notice shall be |
| 22 | + included in all copies or substantial portions of the Software. |
| 23 | + |
| 24 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 25 | + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 26 | + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 27 | + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 28 | + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 29 | + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 30 | + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 31 | + SOFTWARE. |
| 32 | + ==================================================*/ |
| 33 | + |
| 34 | +function tabberObj(argsObj) |
| 35 | +{ |
| 36 | + var arg; /* name of an argument to override */ |
| 37 | + |
| 38 | + /* Element for the main tabber div. If you supply this in argsObj, |
| 39 | + then the init() method will be called. |
| 40 | + */ |
| 41 | + this.div = null; |
| 42 | + |
| 43 | + /* Class of the main tabber div */ |
| 44 | + this.classMain = "tabber"; |
| 45 | + |
| 46 | + /* Rename classMain to classMainLive after tabifying |
| 47 | + (so a different style can be applied) |
| 48 | + */ |
| 49 | + this.classMainLive = "tabberlive"; |
| 50 | + |
| 51 | + /* Class of each DIV that contains a tab */ |
| 52 | + this.classTab = "tabbertab"; |
| 53 | + |
| 54 | + /* Class to indicate which tab should be active on startup */ |
| 55 | + this.classTabDefault = "tabbertabdefault"; |
| 56 | + |
| 57 | + /* Class for the navigation UL */ |
| 58 | + this.classNav = "tabbernav"; |
| 59 | + |
| 60 | + /* When a tab is to be hidden, instead of setting display='none', we |
| 61 | + set the class of the div to classTabHide. In your screen |
| 62 | + stylesheet you should set classTabHide to display:none. In your |
| 63 | + print stylesheet you should set display:block to ensure that all |
| 64 | + the information is printed. |
| 65 | + */ |
| 66 | + this.classTabHide = "tabbertabhide"; |
| 67 | + |
| 68 | + /* Class to set the navigation LI when the tab is active, so you can |
| 69 | + use a different style on the active tab. |
| 70 | + */ |
| 71 | + this.classNavActive = "tabberactive"; |
| 72 | + |
| 73 | + /* Elements that might contain the title for the tab, only used if a |
| 74 | + title is not specified in the TITLE attribute of DIV classTab. |
| 75 | + */ |
| 76 | + this.titleElements = ['h2','h3','h4','h5','h6']; |
| 77 | + |
| 78 | + /* Should we strip out the HTML from the innerHTML of the title elements? |
| 79 | + This should usually be true. |
| 80 | + */ |
| 81 | + this.titleElementsStripHTML = true; |
| 82 | + |
| 83 | + /* If the user specified the tab names using a TITLE attribute on |
| 84 | + the DIV, then the browser will display a tooltip whenever the |
| 85 | + mouse is over the DIV. To prevent this tooltip, we can remove the |
| 86 | + TITLE attribute after getting the tab name. |
| 87 | + */ |
| 88 | + this.removeTitle = true; |
| 89 | + |
| 90 | + /* If you want to add an id to each link set this to true */ |
| 91 | + this.addLinkId = false; |
| 92 | + |
| 93 | + /* If addIds==true, then you can set a format for the ids. |
| 94 | + <tabberid> will be replaced with the id of the main tabber div. |
| 95 | + <tabnumberzero> will be replaced with the tab number |
| 96 | + (tab numbers starting at zero) |
| 97 | + <tabnumberone> will be replaced with the tab number |
| 98 | + (tab numbers starting at one) |
| 99 | + <tabtitle> will be replaced by the tab title |
| 100 | + (with all non-alphanumeric characters removed) |
| 101 | + */ |
| 102 | + this.linkIdFormat = '<tabberid>nav<tabnumberone>'; |
| 103 | + |
| 104 | + /* You can override the defaults listed above by passing in an object: |
| 105 | + var mytab = new tabber({property:value,property:value}); |
| 106 | + */ |
| 107 | + for (arg in argsObj) { this[arg] = argsObj[arg]; } |
| 108 | + |
| 109 | + /* Create regular expressions for the class names; Note: if you |
| 110 | + change the class names after a new object is created you must |
| 111 | + also change these regular expressions. |
| 112 | + */ |
| 113 | + this.REclassMain = new RegExp('\\b' + this.classMain + '\\b', 'gi'); |
| 114 | + this.REclassMainLive = new RegExp('\\b' + this.classMainLive + '\\b', 'gi'); |
| 115 | + this.REclassTab = new RegExp('\\b' + this.classTab + '\\b', 'gi'); |
| 116 | + this.REclassTabDefault = new RegExp('\\b' + this.classTabDefault + '\\b', 'gi'); |
| 117 | + this.REclassTabHide = new RegExp('\\b' + this.classTabHide + '\\b', 'gi'); |
| 118 | + |
| 119 | + /* Array of objects holding info about each tab */ |
| 120 | + this.tabs = new Array(); |
| 121 | + |
| 122 | + /* If the main tabber div was specified, call init() now */ |
| 123 | + if (this.div) { |
| 124 | + |
| 125 | + this.init(this.div); |
| 126 | + |
| 127 | + /* We don't need the main div anymore, and to prevent a memory leak |
| 128 | + in IE, we must remove the circular reference between the div |
| 129 | + and the tabber object. */ |
| 130 | + this.div = null; |
| 131 | + } |
| 132 | +} |
| 133 | + |
| 134 | + |
| 135 | +/*-------------------------------------------------- |
| 136 | + Methods for tabberObj |
| 137 | + --------------------------------------------------*/ |
| 138 | + |
| 139 | + |
| 140 | +tabberObj.prototype.init = function(e) |
| 141 | +{ |
| 142 | + /* Set up the tabber interface. |
| 143 | + |
| 144 | + e = element (the main containing div) |
| 145 | + |
| 146 | + Example: |
| 147 | + init(document.getElementById('mytabberdiv')) |
| 148 | + */ |
| 149 | + |
| 150 | + var |
| 151 | + childNodes, /* child nodes of the tabber div */ |
| 152 | + i, i2, /* loop indices */ |
| 153 | + t, /* object to store info about a single tab */ |
| 154 | + defaultTab=0, /* which tab to select by default */ |
| 155 | + DOM_ul, /* tabbernav list */ |
| 156 | + DOM_li, /* tabbernav list item */ |
| 157 | + DOM_a, /* tabbernav link */ |
| 158 | + aId, /* A unique id for DOM_a */ |
| 159 | + headingElement; /* searching for text to use in the tab */ |
| 160 | + |
| 161 | + /* Verify that the browser supports DOM scripting */ |
| 162 | + if (!document.getElementsByTagName) { return false; } |
| 163 | + |
| 164 | + /* If the main DIV has an ID then save it. */ |
| 165 | + if (e.id) { |
| 166 | + this.id = e.id; |
| 167 | + } |
| 168 | + |
| 169 | + /* Clear the tabs array (but it should normally be empty) */ |
| 170 | + this.tabs.length = 0; |
| 171 | + |
| 172 | + /* Loop through an array of all the child nodes within our tabber element. */ |
| 173 | + childNodes = e.childNodes; |
| 174 | + for(i=0; i < childNodes.length; i++) { |
| 175 | + |
| 176 | + /* Find the nodes where class="tabbertab" */ |
| 177 | + if(childNodes[i].className && |
| 178 | + childNodes[i].className.match(this.REclassTab)) { |
| 179 | + |
| 180 | + /* Create a new object to save info about this tab */ |
| 181 | + t = new Object(); |
| 182 | + |
| 183 | + /* Save a pointer to the div for this tab */ |
| 184 | + t.div = childNodes[i]; |
| 185 | + |
| 186 | + /* Add the new object to the array of tabs */ |
| 187 | + this.tabs[this.tabs.length] = t; |
| 188 | + |
| 189 | + /* If the class name contains classTabDefault, |
| 190 | + then select this tab by default. |
| 191 | + */ |
| 192 | + if (childNodes[i].className.match(this.REclassTabDefault)) { |
| 193 | + defaultTab = this.tabs.length-1; |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 197 | + |
| 198 | + /* Create a new UL list to hold the tab headings */ |
| 199 | + DOM_ul = document.createElement("ul"); |
| 200 | + DOM_ul.className = this.classNav; |
| 201 | + |
| 202 | + /* Loop through each tab we found */ |
| 203 | + for (i=0; i < this.tabs.length; i++) { |
| 204 | + |
| 205 | + t = this.tabs[i]; |
| 206 | + |
| 207 | + /* Get the label to use for this tab: |
| 208 | + From the title attribute on the DIV, |
| 209 | + Or from one of the this.titleElements[] elements, |
| 210 | + Or use an automatically generated number. |
| 211 | + */ |
| 212 | + t.headingText = t.div.title; |
| 213 | + |
| 214 | + /* Remove the title attribute to prevent a tooltip from appearing */ |
| 215 | + if (this.removeTitle) { t.div.title = ''; } |
| 216 | + |
| 217 | + if (!t.headingText) { |
| 218 | + |
| 219 | + /* Title was not defined in the title of the DIV, |
| 220 | + So try to get the title from an element within the DIV. |
| 221 | + Go through the list of elements in this.titleElements |
| 222 | + (typically heading elements ['h2','h3','h4']) |
| 223 | + */ |
| 224 | + for (i2=0; i2<this.titleElements.length; i2++) { |
| 225 | + headingElement = t.div.getElementsByTagName(this.titleElements[i2])[0]; |
| 226 | + if (headingElement) { |
| 227 | + t.headingText = headingElement.innerHTML; |
| 228 | + if (this.titleElementsStripHTML) { |
| 229 | + t.headingText.replace(/<br>/gi," "); |
| 230 | + t.headingText = t.headingText.replace(/<[^>]+>/g,""); |
| 231 | + } |
| 232 | + break; |
| 233 | + } |
| 234 | + } |
| 235 | + } |
| 236 | + |
| 237 | + if (!t.headingText) { |
| 238 | + /* Title was not found (or is blank) so automatically generate a |
| 239 | + number for the tab. |
| 240 | + */ |
| 241 | + t.headingText = i + 1; |
| 242 | + } |
| 243 | + |
| 244 | + /* Create a list element for the tab */ |
| 245 | + DOM_li = document.createElement("li"); |
| 246 | + |
| 247 | + /* Save a reference to this list item so we can later change it to |
| 248 | + the "active" class */ |
| 249 | + t.li = DOM_li; |
| 250 | + |
| 251 | + /* Create a link to activate the tab */ |
| 252 | + DOM_a = document.createElement("a"); |
| 253 | + DOM_a.appendChild(document.createTextNode(t.headingText)); |
| 254 | + DOM_a.href = "javascript:void(null);"; |
| 255 | + DOM_a.title = t.headingText; |
| 256 | + DOM_a.onclick = this.navClick; |
| 257 | + |
| 258 | + /* Add some properties to the link so we can identify which tab |
| 259 | + was clicked. Later the navClick method will need this. |
| 260 | + */ |
| 261 | + DOM_a.tabber = this; |
| 262 | + DOM_a.tabberIndex = i; |
| 263 | + |
| 264 | + /* Do we need to add an id to DOM_a? */ |
| 265 | + if (this.addLinkId && this.linkIdFormat) { |
| 266 | + |
| 267 | + /* Determine the id name */ |
| 268 | + aId = this.linkIdFormat; |
| 269 | + aId = aId.replace(/<tabberid>/gi, this.id); |
| 270 | + aId = aId.replace(/<tabnumberzero>/gi, i); |
| 271 | + aId = aId.replace(/<tabnumberone>/gi, i+1); |
| 272 | + aId = aId.replace(/<tabtitle>/gi, t.headingText.replace(/[^a-zA-Z0-9\-]/gi, '')); |
| 273 | + |
| 274 | + DOM_a.id = aId; |
| 275 | + } |
| 276 | + |
| 277 | + /* Add the link to the list element */ |
| 278 | + DOM_li.appendChild(DOM_a); |
| 279 | + |
| 280 | + /* Add the list element to the list */ |
| 281 | + DOM_ul.appendChild(DOM_li); |
| 282 | + } |
| 283 | + |
| 284 | + /* Add the UL list to the beginning of the tabber div */ |
| 285 | + e.insertBefore(DOM_ul, e.firstChild); |
| 286 | + |
| 287 | + /* Make the tabber div "live" so different CSS can be applied */ |
| 288 | + e.className = e.className.replace(this.REclassMain, this.classMainLive); |
| 289 | + |
| 290 | + /* Activate the default tab, and do not call the onclick handler */ |
| 291 | + this.tabShow(defaultTab); |
| 292 | + |
| 293 | + /* If the user specified an onLoad function, call it now. */ |
| 294 | + if (typeof this.onLoad == 'function') { |
| 295 | + this.onLoad({tabber:this}); |
| 296 | + } |
| 297 | + |
| 298 | + return this; |
| 299 | +}; |
| 300 | + |
| 301 | + |
| 302 | +tabberObj.prototype.navClick = function(event) |
| 303 | +{ |
| 304 | + /* This method should only be called by the onClick event of an <A> |
| 305 | + element, in which case we will determine which tab was clicked by |
| 306 | + examining a property that we previously attached to the <A> |
| 307 | + element. |
| 308 | + |
| 309 | + Since this was triggered from an onClick event, the variable |
| 310 | + "this" refers to the <A> element that triggered the onClick |
| 311 | + event (and not to the tabberObj). |
| 312 | + |
| 313 | + When tabberObj was initialized, we added some extra properties |
| 314 | + to the <A> element, for the purpose of retrieving them now. Get |
| 315 | + the tabberObj object, plus the tab number that was clicked. |
| 316 | + */ |
| 317 | + |
| 318 | + var |
| 319 | + rVal, /* Return value from the user onclick function */ |
| 320 | + a, /* element that triggered the onclick event */ |
| 321 | + self, /* the tabber object */ |
| 322 | + tabberIndex, /* index of the tab that triggered the event */ |
| 323 | + onClickArgs; /* args to send the onclick function */ |
| 324 | + |
| 325 | + a = this; |
| 326 | + if (!a.tabber) { return false; } |
| 327 | + |
| 328 | + self = a.tabber; |
| 329 | + tabberIndex = a.tabberIndex; |
| 330 | + |
| 331 | + /* Remove focus from the link because it looks ugly. |
| 332 | + I don't know if this is a good idea... |
| 333 | + */ |
| 334 | + a.blur(); |
| 335 | + |
| 336 | + /* If the user specified an onClick function, call it now. |
| 337 | + If the function returns false then do not continue. |
| 338 | + */ |
| 339 | + if (typeof self.onClick == 'function') { |
| 340 | + |
| 341 | + onClickArgs = {'tabber':self, 'index':tabberIndex, 'event':event}; |
| 342 | + |
| 343 | + /* IE uses a different way to access the event object */ |
| 344 | + if (!event) { onClickArgs.event = window.event; } |
| 345 | + |
| 346 | + rVal = self.onClick(onClickArgs); |
| 347 | + if (rVal === false) { return false; } |
| 348 | + } |
| 349 | + |
| 350 | + self.tabShow(tabberIndex); |
| 351 | + |
| 352 | + return false; |
| 353 | +}; |
| 354 | + |
| 355 | + |
| 356 | +tabberObj.prototype.tabHideAll = function() |
| 357 | +{ |
| 358 | + var i; /* counter */ |
| 359 | + |
| 360 | + /* Hide all tabs and make all navigation links inactive */ |
| 361 | + for (i = 0; i < this.tabs.length; i++) { |
| 362 | + this.tabHide(i); |
| 363 | + } |
| 364 | +}; |
| 365 | + |
| 366 | + |
| 367 | +tabberObj.prototype.tabHide = function(tabberIndex) |
| 368 | +{ |
| 369 | + var div; |
| 370 | + |
| 371 | + if (!this.tabs[tabberIndex]) { return false; } |
| 372 | + |
| 373 | + /* Hide a single tab and make its navigation link inactive */ |
| 374 | + div = this.tabs[tabberIndex].div; |
| 375 | + |
| 376 | + /* Hide the tab contents by adding classTabHide to the div */ |
| 377 | + if (!div.className.match(this.REclassTabHide)) { |
| 378 | + div.className += ' ' + this.classTabHide; |
| 379 | + } |
| 380 | + this.navClearActive(tabberIndex); |
| 381 | + |
| 382 | + return this; |
| 383 | +}; |
| 384 | + |
| 385 | + |
| 386 | +tabberObj.prototype.tabShow = function(tabberIndex) |
| 387 | +{ |
| 388 | + /* Show the tabberIndex tab and hide all the other tabs */ |
| 389 | + |
| 390 | + var div; |
| 391 | + |
| 392 | + if (!this.tabs[tabberIndex]) { return false; } |
| 393 | + |
| 394 | + /* Hide all the tabs first */ |
| 395 | + this.tabHideAll(); |
| 396 | + |
| 397 | + /* Get the div that holds this tab */ |
| 398 | + div = this.tabs[tabberIndex].div; |
| 399 | + |
| 400 | + /* Remove classTabHide from the div */ |
| 401 | + div.className = div.className.replace(this.REclassTabHide, ''); |
| 402 | + |
| 403 | + /* Mark this tab navigation link as "active" */ |
| 404 | + this.navSetActive(tabberIndex); |
| 405 | + |
| 406 | + /* If the user specified an onTabDisplay function, call it now. */ |
| 407 | + if (typeof this.onTabDisplay == 'function') { |
| 408 | + this.onTabDisplay({'tabber':this, 'index':tabberIndex}); |
| 409 | + } |
| 410 | + |
| 411 | + return this; |
| 412 | +}; |
| 413 | + |
| 414 | +tabberObj.prototype.navSetActive = function(tabberIndex) |
| 415 | +{ |
| 416 | + /* Note: this method does *not* enforce the rule |
| 417 | + that only one nav item can be active at a time. |
| 418 | + */ |
| 419 | + |
| 420 | + /* Set classNavActive for the navigation list item */ |
| 421 | + this.tabs[tabberIndex].li.className = this.classNavActive; |
| 422 | + |
| 423 | + return this; |
| 424 | +}; |
| 425 | + |
| 426 | + |
| 427 | +tabberObj.prototype.navClearActive = function(tabberIndex) |
| 428 | +{ |
| 429 | + /* Note: this method does *not* enforce the rule |
| 430 | + that one nav should always be active. |
| 431 | + */ |
| 432 | + |
| 433 | + /* Remove classNavActive from the navigation list item */ |
| 434 | + this.tabs[tabberIndex].li.className = ''; |
| 435 | + |
| 436 | + return this; |
| 437 | +}; |
| 438 | + |
| 439 | + |
| 440 | +/*==================================================*/ |
| 441 | + |
| 442 | + |
| 443 | +function tabberAutomatic(tabberArgs) |
| 444 | +{ |
| 445 | + /* This function finds all DIV elements in the document where |
| 446 | + class=tabber.classMain, then converts them to use the tabber |
| 447 | + interface. |
| 448 | + |
| 449 | + tabberArgs = an object to send to "new tabber()" |
| 450 | + */ |
| 451 | + var |
| 452 | + tempObj, /* Temporary tabber object */ |
| 453 | + divs, /* Array of all divs on the page */ |
| 454 | + i; /* Loop index */ |
| 455 | + |
| 456 | + if (!tabberArgs) { tabberArgs = {}; } |
| 457 | + |
| 458 | + /* Create a tabber object so we can get the value of classMain */ |
| 459 | + tempObj = new tabberObj(tabberArgs); |
| 460 | + |
| 461 | + /* Find all DIV elements in the document that have class=tabber */ |
| 462 | + |
| 463 | + /* First get an array of all DIV elements and loop through them */ |
| 464 | + divs = document.getElementsByTagName("div"); |
| 465 | + for (i=0; i < divs.length; i++) { |
| 466 | + |
| 467 | + /* Is this DIV the correct class? */ |
| 468 | + if (divs[i].className && |
| 469 | + divs[i].className.match(tempObj.REclassMain)) { |
| 470 | + |
| 471 | + /* Now tabify the DIV */ |
| 472 | + tabberArgs.div = divs[i]; |
| 473 | + divs[i].tabber = new tabberObj(tabberArgs); |
| 474 | + } |
| 475 | + } |
| 476 | + |
| 477 | + return this; |
| 478 | +} |
| 479 | + |
| 480 | + |
| 481 | +/*==================================================*/ |
| 482 | + |
| 483 | + |
| 484 | +function tabberAutomaticOnLoad(tabberArgs) |
| 485 | +{ |
| 486 | + /* This function adds tabberAutomatic to the window.onload event, |
| 487 | + so it will run after the document has finished loading. |
| 488 | + */ |
| 489 | + var oldOnLoad; |
| 490 | + |
| 491 | + if (!tabberArgs) { tabberArgs = {}; } |
| 492 | + |
| 493 | + /* Taken from: http://simon.incutio.com/archive/2004/05/26/addLoadEvent */ |
| 494 | + |
| 495 | + oldOnLoad = window.onload; |
| 496 | + if (typeof window.onload != 'function') { |
| 497 | + window.onload = function() { |
| 498 | + tabberAutomatic(tabberArgs); |
| 499 | + }; |
| 500 | + } else { |
| 501 | + window.onload = function() { |
| 502 | + oldOnLoad(); |
| 503 | + tabberAutomatic(tabberArgs); |
| 504 | + }; |
| 505 | + } |
| 506 | +} |
| 507 | + |
| 508 | + |
| 509 | +/*==================================================*/ |
| 510 | + |
| 511 | + |
| 512 | +/* Run tabberAutomaticOnload() unless the "manualStartup" option was specified */ |
| 513 | + |
| 514 | +if (typeof tabberOptions == 'undefined') { |
| 515 | + |
| 516 | + tabberAutomaticOnLoad(); |
| 517 | + |
| 518 | +} else { |
| 519 | + |
| 520 | + if (!tabberOptions['manualStartup']) { |
| 521 | + tabberAutomaticOnLoad(tabberOptions); |
| 522 | + } |
| 523 | + |
| 524 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/Tabber/Tabber.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 525 | + native |