/* Tab Set
Defines a group of related tabs, with classes to show active and
inactive tabs. Internal mechanisms keep track of which tab in the TabSet is
currently active.
Arguments:
id: unique identifier for the TabSet
activeClass: name of a CSS class that defines the stype of the active tab
inactiveClass: name of a CSS class that defines the style of inactive tabs
*/
function TabSet(id,activeClass,inactiveClass) {
this.id = id;
this.tm = null; // this will be set by the TabManager
this.activeClass = activeClass;
this.inactiveClass = inactiveClass;
this.activeTab = null;
this.activeTabName = null;
this.tabs = new Array();
this.tabCount = 0;
this.element = getElement("TabSet",id); // DOM element for the TabSet
// (usually an html
}
/* methods */
TabSet.prototype.addTab=addTabToTabSet;
TabSet.prototype.activateTab=activateTab;
TabSet.prototype.show=showTabSet;
TabSet.prototype.hide=hideTabSet;
// add a tab to the TabSet
function addTabToTabSet(tab) {
// this.tabs.push(tab);
// give it a reference to the Tab Manager
tab.tm = this.tm;
tab.element =
this.tabs[tab.id] = tab;
this.tabCount++;
}
// make tab with id 'id' the active tab in the Tabset
function activateTab(id, activate) {
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - ENTRY");
var newTab = document.getElementById(id);
var oldTab;
var i;
if (newTab == null) {
error("TabSet[" + this.id + "].activateTab()","no tab '" + id + "' in tabs");
return;
}
if (activate==true) {
if (this.activeTab != null) {
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - inactivating tab " + this.activeTabName);
if(this.inactiveClass != null) this.activeTab.className = this.inactiveClass;
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - applied classname " + this.inactiveClass);
} else {
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - no active active tab");
}
//
if(this.activeClass != null) newTab.className = this.activeClass;
this.activeTab = newTab;
this.activeTabName = id;
} else {
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - inactivating tab " + id);
if(this.inactiveClass != null) newTab.className = this.inactiveClass;
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - applied classname " + this.inactiveClass);
}
console.log("Tabset[" + this.id + "].activateTab(" + id + ") - EXIT");
}
// show this TabSet - make it visible.
function showTabSet() {
this.element.style.visibility='visible';
}
// hide this TabSet - make it invisible.
function hideTabSet() {
this.element.style.visibility='hidden';
}
/* ----
TabSet.prototype.loadTab=loadTab;
function loadTab(id) {
var newTab = this.items[id];
if (newTab == null) {
error("TabSet.loadTab()","no item '" + id + "' in items");
return;
}
if (this.activeTab != null) this.activeTab.dim();
newTab.light();
this.activeTab = newTab;
if (newTab.url != null) newTab.load();
//this.tm.loadURL(newTab.url);
}
*/
function TabManager(doc, iFrameId, defaultHeight) {
this.tabSets = new Array();
this.tabs = new Array();
this.tabCount = 0;
this.doc = doc;
this.iFrame = getElement("TabManager",iFrameId);
this.defaultHeight = defaultHeight;
this.activeTabSet = null;
}
TabManager.prototype.addTabSet=addTabSet;
TabManager.prototype.addTab=addTab;
TabManager.prototype.loadTab=loadTab;
TabManager.prototype.highlightTab=highlightTab;
TabManager.prototype.getDocHeight=getDocHeight;
TabManager.prototype.getAvailableHeight=getAvailableHeight;
TabManager.prototype.setFrameHeight=setFrameHeight;
TabManager.prototype.fillFrameHeight=fillFrameHeight;
TabManager.prototype.fixFrameHeight=fixFrameHeight;
TabManager.prototype.loadURL=tmLoadURL;
function tmLoadURL(url) {
this.iFrame.src = url;
}
// add a tab set
function addTabSet(tabSet) {
tabSet.tm = this;
this.tabSets[tabSet.id] = tabSet;
}
// add a tab
function addTab(tab) {
//console.log("TabManager.addTab(" + tab.id + ")");
this.tabs[tab.id]=tab;
this.tabCount = this.tabCount+1;
//console.log("TabManager.addTab(" + tab.id + ") length is " + this.tabs.length + "/" + this.tabCount);
}
// load the HTML for a tab into the iFrame
function loadTab(id) {
var tab = this.tabs[id];
if (tab == null) {
error("TabManager.loadTab()","no tab '" + id + "' in tabs");
return;
}
this.iFrame.src = tab.url;
}
// Call triggered by the onload or onunload event of the tab's HTML page.
function highlightTab(id, activate) {
// first get the tab in question
//console.log("TM.highlightTab(" + id + "): - ENTRY");
var tab = this.tabs[id];
if (tab == null) {
error("TabManager.activateTab()","no tab '" + id + "' in tabs");
return;
}
// and set its height
//console.log("TM.highlightTab(" + id + "): - setting Height");
//console.log("TM.highlightTab(" + id + "): - set Height");
// Highlight the main (top menu) tab
if (tab.mainTabId != null) {
//console.log("TM.highlightTab(" + id + "): - getting Main Tab for " + tab.mainTabId);
var mainTab = this.tabs[tab.mainTabId];
if (mainTab == null) {
error("TabManager.activateTab()","no main tab '" + tab.mainTabId + "' in tabSets");
return;
}
//console.log("TM.highlightTab(" + id + "): - activating mainTabSet " + tab.mainTabId);
var mainTabSet = this.tabSets["mainTabs"];
mainTabSet.activateTab(tab.mainTabId, activate);
} else {
// console.log("TM.highlightTab(" + id + "): - no mainTabId for Id");
}
// Highlight the sub Tab (if need be)
if (tab.subTabId != null) {
// console.log("TM.highlightTab(" + id + "): - getting suTabSet for " + tab.subTabId);
var subTabSet = this.tabSets[tab.subTabId];
if (subTabSet == null) {
error("TabManager.activateTab()","no sub tabset '" + tab.subTabId + "' in tabSets");
return;
}
if (this.activeTabSet != subTabSet) {
if (this.activeTabSet != null) this.activeTabSet.hide();
subTabSet.show();
this.activeTabSet = subTabSet;
}
subTabSet.activateTab(id, activate);
} else {
//console.log("TM.highlightTab(" + id + "): - no subTabSet for id");
}
// console.log("TM.highlightTab(" + id + "): - EXIT");
}
function fillFrameHeight(id) {
//console.log("fillFrameHeight(" + id + ") - ENTRY");
this.iFrame.style.visibility = 'hidden';
this.iFrame.style.height = "0px";
var height = this.getAvailableHeight(id);
//console.log("fillFrameHeight(" + id + ") - using height " + height);
this.iFrame.style.height = height + "px";
this.iFrame.style.visibility = 'visible';
//console.log("fillFrameHeight(" + id + ") - EXIT");
}
function fixFrameHeight(id, height) {
//console.log("fixFrameHeight(" + id + ") - ENTRY");
this.iFrame.style.visibility = 'hidden';
this.iFrame.style.height = "0px";
//console.log("fixFrameHeight(" + id + ") - using height " + height);
this.iFrame.style.height = height + "px";
this.iFrame.style.visibility = 'visible';
//console.log("fixFrameHeight(" + id + ") - EXIT");
}
//Sets the iframe element's height to match the
//contained document's height.
function setFrameHeight(id) {
//console.log("setFrameHeight(" + id + ") - ENTRY");
this.iFrame.style.visibility = 'hidden';
this.iFrame.style.height = "0px";
var height;
var docHeight = this.getDocHeight(id);
var availableHeight = this.getAvailableHeight(id);
//alert("docHeight is " + docHeight + ", availableHeight is " + availableHeight);
// reset to minimal height ...
if (docHeight <= availableHeight || isNaN(availableHeight)) {
height = docHeight;
//console.log("setFrameHeight(" + id + ") - using docHeight " + height);
} else {
height = availableHeight;
//console.log("setFrameHeight(" + id + ") - using available Height " + height);
}
//alert("setting height " + height);
this.iFrame.style.height = height + "px";
//alert("set height, setting visibility");
this.iFrame.style.visibility = 'visible';
//alert("set visibility");
//console.log("setHeight(" + id + ") - EXIT");
}
function getDocHeight(id) {
// clientHeight: the viewable height of the content on a page (not including borders, margins, or scrollbars)
// scrollHeight: the entire height of an element (including areas hidden with scrollbars)
// offsetHeight: the height of an element, including borders and padding if any, but not margins
var doc;
var body;
var html;
var height = this.defaultHeight;
try {
if (this.iFrame.contentDocument != null) {
doc = this.iFrame.contentDocument;
//console.log("getDocHeight(" + id + ") - doc = this.iFrame.contentDocument");
} else {
if (this.iFrame.contentWindow.document != null) {
doc = this.iFrame.contentWindow.document;
//console.log("getDocHeight(" + id + ") - doc = this.iFrame.contentDocument");
} else {
doc = null;
}
}
if (doc == null) {
//console.log("getDocHeight(" + id + ") - doc = null");
//console.log("getDocHeight(" + id + "): defaulting height: " + height);
return height;
}
body = doc.body;
html = doc.documentElement;
height = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight );
//console.log("getDocHeight(" + id + "): calculating height: " + height);
} catch(e) {
//console.log("getDocHeight(" + id + "): caught exception :" + e);
//console.log("getDocHeight(" + id + "): defaulting height: " + height);
}
return height;
}
function getAvailableHeight(id) {
// it's the window height, less the bit above the frame.
var height;
//console.log("getAvailableHeight(" + id + "): window.height = " + window.innerHeight);
//console.log("getAvailableHeight(" + id + "): frame offset = " + this.iFrame.offsetTop);
height = window.innerHeight - this.iFrame.offsetTop;
//console.log("getAvailableHeight(" + id + "): available height = " + height);
return height;
}
function Tab(id, mainTabId, subTabId, url) {
this.id = id;
this.mainTabId = mainTabId;
this.subTabId = subTabId;
this.url = url;
}
// Utility function to fetch a document element and output an error if it isn't there.
function getElement(fn,id) {
var element = document.getElementById(id);
if (element == null) {
error(fn,"no element in document with id '" + id + "'");
}
return element;
}
function error(fn,mess) {
alert(fn + ": " + mess);
console.log(fn + ": " + mess);
}