// SpryTabbedPanels.js - version 0.5 - Spry Pre-Release 1.6//// Copyright (c) 2006. Adobe Systems Incorporated.// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met:////   * Redistributions of source code must retain the above copyright notice,//     this list of conditions and the following disclaimer.//   * Redistributions in binary form must reproduce the above copyright notice,//     this list of conditions and the following disclaimer in the documentation//     and/or other materials provided with the distribution.//   * Neither the name of Adobe Systems Incorporated nor the names of its//     contributors may be used to endorse or promote products derived from this//     software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE// POSSIBILITY OF SUCH DAMAGE.var Spry;if (!Spry) Spry = {};if (!Spry.Widget) Spry.Widget = {};Spry.Widget.TabbedPanels = function(element, opts){this.element = this.getElement(element);this.defaultTab = 0; // Show the first panel by default.this.tabSelectedClass = "TabbedPanelsTabSelected";this.tabHoverClass = "TabbedPanelsTabHover";this.tabFocusedClass = "TabbedPanelsTabFocused";this.panelVisibleClass = "TabbedPanelsContentVisible";this.focusElement = null;this.hasFocus = false;this.currentTabIndex = 0;this.enableKeyboardNavigation = true;Spry.Widget.TabbedPanels.setOptions(this, opts);// If the defaultTab is expressed as a number/index, convert// it to an element.if (typeof (this.defaultTab) == "number"){if (this.defaultTab < 0)this.defaultTab = 0;else{var count = this.getTabbedPanelCount();if (this.defaultTab >= count)this.defaultTab = (count > 1) ? (count - 1) : 0;}this.defaultTab = this.getTabs()[this.defaultTab];}// The defaultTab property is supposed to be the tab element for the tab content// to show by default. The caller is allowed to pass in the element itself or the// element's id, so we need to convert the current value to an element if necessary.if (this.defaultTab)this.defaultTab = this.getElement(this.defaultTab);this.attachBehaviors();};Spry.Widget.TabbedPanels.prototype.getElement = function(ele){if (ele && typeof ele == "string")return document.getElementById(ele);return ele;};Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element){var children = [];var child = element.firstChild;while (child){if (child.nodeType == 1 /* Node.ELEMENT_NODE */)children.push(child);child = child.nextSibling;}return children;};Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className){if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))return;ele.className += (ele.className ? " " : "") + className;};Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className){if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))return;ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");};Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps){if (!optionsObj)return;for (var optionName in optionsObj){if (ignoreUndefinedProps && optionsObj[optionName] == undefined)continue;obj[optionName] = optionsObj[optionName];}};Spry.Widget.TabbedPanels.prototype.getTabGroup = function(){if (this.element){var children = this.getElementChildren(this.element);if (children.length)return children[0];}return null;};Spry.Widget.TabbedPanels.prototype.getTabs = function(){var tabs = [];var tg = this.getTabGroup();if (tg)tabs = this.getElementChildren(tg);return tabs;};Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function(){if (this.element){var children = this.getElementChildren(this.element);if (children.length > 1)return children[1];}return null;};Spry.Widget.TabbedPanels.prototype.getContentPanels = function(){var panels = [];var pg = this.getContentPanelGroup();if (pg)panels = this.getElementChildren(pg);return panels;};Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr){ele = this.getElement(ele);if (ele && arr && arr.length){for (var i = 0; i < arr.length; i++){if (ele == arr[i])return i;}}return -1;};Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele){var i = this.getIndex(ele, this.getTabs());if (i < 0)i = this.getIndex(ele, this.getContentPanels());return i;};Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function(){return this.currentTabIndex;};Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele){return Math.min(this.getTabs().length, this.getContentPanels().length);};Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture){try{if (element.addEventListener)element.addEventListener(eventType, handler, capture);else if (element.attachEvent)element.attachEvent("on" + eventType, handler);}catch (e) {}};Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab){this.showPanel(tab);if (e.preventDefault) e.preventDefault();else e.returnValue = false;if (e.stopPropagation) e.stopPropagation();else e.cancelBubble = true;return false;};Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab){this.addClassName(tab, this.tabHoverClass);return false;};Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab){this.removeClassName(tab, this.tabHoverClass);return false;};Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab){this.hasFocus = true;this.addClassName(tab, this.tabFocusedClass);return false;};Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab){this.hasFocus = false;this.removeClassName(tab, this.tabFocusedClass);return false;};Spry.Widget.TabbedPanels.ENTER_KEY = 13;Spry.Widget.TabbedPanels.SPACE_KEY = 32;Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab){var key = e.keyCode;if (!this.hasFocus || (key != Spry.Widget.TabbedPanels.ENTER_KEY && key != Spry.Widget.TabbedPanels.SPACE_KEY))return true;this.showPanel(tab);if (e.preventDefault) e.preventDefault();else e.returnValue = false;if (e.stopPropagation) e.stopPropagation();else e.cancelBubble = true;return false;};Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func){var stopTraversal = false;if (root){stopTraversal = func(root);if (root.hasChildNodes()){var child = root.firstChild;while (!stopTraversal && child){stopTraversal = this.preorderTraversal(child, func);try { child = child.nextSibling; } catch (e) { child = null; }}}}return stopTraversal;};Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel){var self = this;Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);if (this.enableKeyboardNavigation){// XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't// rely on adding the tabindex attribute if it is missing to enable keyboard navigation// by default.// Find the first element within the tab container that has a tabindex or the first// anchor tag.var tabIndexEle = null;var tabAnchorEle = null;this.preorderTraversal(tab, function(node) {if (node.nodeType == 1 /* NODE.ELEMENT_NODE */){var tabIndexAttr = tab.attributes.getNamedItem("tabindex");if (tabIndexAttr){tabIndexEle = node;return true;}if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")tabAnchorEle = node;}return false;});if (tabIndexEle)this.focusElement = tabIndexEle;else if (tabAnchorEle)this.focusElement = tabAnchorEle;if (this.focusElement){Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);}}};Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex){var tpIndex = -1;if (typeof elementOrIndex == "number")tpIndex = elementOrIndex;else // Must be the element for the tab or content panel.tpIndex = this.getTabIndex(elementOrIndex);if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())return;var tabs = this.getTabs();var panels = this.getContentPanels();var numTabbedPanels = Math.max(tabs.length, panels.length);for (var i = 0; i < numTabbedPanels; i++){if (i != tpIndex){if (tabs[i])this.removeClassName(tabs[i], this.tabSelectedClass);if (panels[i]){this.removeClassName(panels[i], this.panelVisibleClass);panels[i].style.display = "none";}}}this.addClassName(tabs[tpIndex], this.tabSelectedClass);this.addClassName(panels[tpIndex], this.panelVisibleClass);panels[tpIndex].style.display = "block";this.currentTabIndex = tpIndex;};Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element){var tabs = this.getTabs();var panels = this.getContentPanels();var panelCount = this.getTabbedPanelCount();for (var i = 0; i < panelCount; i++)this.addPanelEventListeners(tabs[i], panels[i]);this.showPanel(this.defaultTab);};
