File: //home/bk/efi/eficenter.ru/js/MSFlyoutClass.js
/**
* The MSFlyout Class handles the Flyout Menus on the website.
* It offers timeout values that can be different for each
* flyout type. This class depends on the daimler_basic.js!
*
* @author Stefan.Bechtold(at)namics.com
* @version 1.0
* @requires daimler_basic.js
* @requires navigation.js
*/
// Class MSFlyout, Constructor
function MSFlyout(/*String*/ id, /*int*/ type) {
this.id = id;
this.type = type;
this.active = false;
// Get Layer for this Flyout
if (id) {
this.flyout = getLayer(id);
}
// Check and extend global MSFlyout list if necessary
if (!MSFlyout.flyouts[type]) {
MSFlyout.flyouts[type] = new Array();
}
// Add flyout to global MSFlyout object
MSFlyout.flyouts[type][id] = this;
// Add event listener for this flyout
if (this.flyout) {
addEvent(this.flyout, "mouseover", function() { MSFlyout.flyouts[type][id].activate() }, true);
addEvent(this.flyout, "mouseout", function() { MSFlyout.flyouts[type][id].deactivate() }, true);
}
}
// Static Flyout Types
MSFlyout.TYPE_CORENAV1 = 1;
MSFlyout.TYPE_CORENAV2 = 2;
MSFlyout.TYPE_PCN_BUTTON = 3;
MSFlyout.TYPE_PCN_MENU = 4;
MSFlyout.TYPE_METANAVLOGIN = 5;
// Static Timeout Settings
MSFlyout.ACTIVATION_TIMEOUT = new Array();
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV1] = 200;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV2] = 500;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON] = 200;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 250;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVLOGIN] = 250;
MSFlyout.DEACTIVATION_TIMEOUT = new Array();
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV1] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV2] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVLOGIN] = 200;
// Static CSS Settings
MSFlyout.CSS_CLASS_ACTIVE = "ms-active";
MSFlyout.CSS_CLASS_HOVER = "ms-fly-hover";
// Static Vars
MSFlyout.flyouts = new Array();
MSFlyout.openFlyout = new Array();
MSFlyout.changeTimeout = new Array();
MSFlyout.closeTimeout = new Array();
// Static Methods
MSFlyout.change = function(/*String*/ id, /*int*/ type) {
// Close open MSFlyout Menu
if (MSFlyout.openFlyout[type]) {
MSFlyout.openFlyout[type].handleDeactivate();
}
// Open new MSFlyout Menu
if (MSFlyout.flyouts[type][id]) {
MSFlyout.flyouts[type][id].handleActivate();
}
}
MSFlyout.closeAll = function(/*int*/ type) {
// Close all open MSFlyout Menus
for (var flyout in MSFlyout.flyouts[type]) {
if (MSFlyout.flyouts[type][flyout].active) {
MSFlyout.flyouts[type][flyout].handleDeactivate();
}
}
// Reset openFlyout Reference
MSFlyout.openFlyout[type] = undefined;
}
MSFlyout.pushClass = function(object, className) {
var /*String*/ objClasses = getClassName(object);
if (objClasses.indexOf(className) == -1) {
objClasses += " " + className;
}
setClass(object, objClasses);
}
//push class for the MetaNavigation
MSFlyout.pushClassMN = function(object) {
object.style.display = "block";
}
MSFlyout.popClass = function(object, className) {
var /*String*/ objClasses = getClassName(object);
var /*int*/ posClassName = objClasses.indexOf(className);
if (posClassName != -1) {
if (posClassName + className.length < objClasses.length) {
objClasses = objClasses.substring(0, posClassName) + objClasses.substring(posClassName + className.length);
} else {
objClasses = objClasses.substring(0, posClassName);
}
}
setClass(object, objClasses);
}
//pop class for the MetaNavigation
MSFlyout.popClassMN = function(object) {
object.style.display = "none";
}
// Methods
MSFlyout.prototype.activate = function() {
// Clear Closing Timeout
clearTimeout(MSFlyout.changeTimeout[this.type]);
clearTimeout(MSFlyout.closeTimeout[this.type]);
// Closing all independend, open menus
for (var type in MSFlyout.openFlyout) {
var /*boolean*/ isIndependend = true;
switch (this.type) {
// Core Navigation flyouts
case MSFlyout.TYPE_CORENAV1:
case MSFlyout.TYPE_CORENAV2:
isIndependend = ((type != MSFlyout.TYPE_CORENAV1)
&& (type != MSFlyout.TYPE_CORENAV2));
break;
// PCN Flyouts
case MSFlyout.TYPE_PCN_BUTTON:
case MSFlyout.TYPE_PCN_MENU:
isIndependend = ((type != MSFlyout.TYPE_PCN_BUTTON)
&& (type != MSFlyout.TYPE_PCN_MENU));
break;
case MSFlyout.TYPE_METANAVLOGIN:
}
// If current flyout type is independend and has open flyouts, close them
if (isIndependend && MSFlyout.openFlyout[type]) {
MSFlyout.closeAll(type);
}
}
if (MSFlyout.openFlyout[this.type] == undefined) {
// If no MSFlyout Menu is open, strictly open the current one
this.handleActivate();
} else if (MSFlyout.openFlyout[this.type] != this) {
MSFlyout.changeTimeout[this.type] = setTimeout("MSFlyout.change(\"" + this.id + "\", \"" + this.type + "\")", MSFlyout.ACTIVATION_TIMEOUT[this.type]);
}
}
MSFlyout.prototype.handleActivate = function() {
// Call Ajax Request for Core Navigation 2 Flyout
if (this.type == MSFlyout.TYPE_CORENAV2) {
var /*String[]*/ values = this.id.split("@");
var /*String*/ elementId = values[0];
var /*String*/ handle = values[1];
ms_corenav_loadFlyoutData(elementId, handle);
} else {
ms_setIFrameHeight(this.flyout.id);
}
// Activate MSFlyout
if (this.type == MSFlyout.TYPE_METANAVLOGIN) {
this.active = true;
MSFlyout.pushClassMN(this.flyout);
}
else {
this.active = true;
MSFlyout.pushClass(this.flyout, MSFlyout.CSS_CLASS_HOVER);
}
// Set openFlyout Reference
MSFlyout.openFlyout[this.type] = this;
/* ********************************************* */
// Avoiding, that the flyout becomes hidden
// behind the bottom border of the browser.
/* ********************************************* */
// Only for PCN and SUBNAVIGATION
if (this.type == MSFlyout.TYPE_PCN_BUTTON || this.type == MSFlyout.TYPE_PCN_MENU) {
if (this.flyout && this.flyout.getElementsByTagName("div") &&
this.flyout.getElementsByTagName("div").length > 0) {
// Check for IE
var isIE = (document.all && !window.opera);
// Calculate flyoutTop position
var flyoutOffset = 0;
var flyoutMenu = this.flyout.getElementsByTagName("div")[0];
if (flyoutMenu.lastChild && flyoutMenu.lastChild.childNodes.length > 0) {
var childNodes = flyoutMenu.lastChild.childNodes;
for (var i = 0; i < childNodes.length; i++) {
if (childNodes[i].nodeName == "LI") {
flyoutOffset += childNodes[i].offsetHeight;
}
}
}
// Get positions of page elements
var buttonTop = getAbsTop(this.flyout);
var footerHeight = getLayer("ms-footer").offsetHeight;
if (isIE) {
var innerHeight = document.documentElement.clientHeight - footerHeight;
var pageOffset = document.documentElement.scrollTop;
} else {
var innerHeight = window.innerHeight - footerHeight;
var pageOffset = window.pageYOffset;
}
// Check if flyout menu would be visibile
var lowestY = buttonTop + flyoutOffset - pageOffset;
if (lowestY > innerHeight) {
// Set position from the button
flyoutMenu.style.bottom = "0px";
flyoutMenu.style.top = "auto"; // need to overwrite!
// IE needs a height for the outer element to work correctly
if (isIE && (getIEVersion()>0)&& (getIEVersion()<7) && this.flyout) {
this.flyout.style.height = this.flyout.offsetHeight + "px";
}
} else {
// Remove inline styles
if (isIE) {
flyoutMenu.style.removeAttribute("bottom", false);
flyoutMenu.style.removeAttribute("position", false);
flyoutMenu.style.removeAttribute("top", false);
} else {
flyoutMenu.style.bottom = "";
flyoutMenu.style.position = "";
flyoutMenu.style.top = "";
}
}
}
}
/* ********************************************* */
// Avoiding, that the flyout becomes hidden
// behind the bottom border of the browser.
/* ********************************************* */
}
function getIEVersion() {
try {
if (navigator.appName=="Microsoft Internet Explorer" && navigator.appVersion.indexOf("MSIE")>0) {
var str = navigator.appVersion;
var ind = parseInt(str.indexOf("MSIE"))+5;
var ver = parseInt(str.substring(ind, ind+1));
return ver;
} else {
return 0;
}
} catch(e) {}
}
MSFlyout.prototype.deactivate = function() {
// Set Closing Timeout
MSFlyout.closeTimeout[this.type] = setTimeout("MSFlyout.closeAll(\"" + this.type + "\")", MSFlyout.DEACTIVATION_TIMEOUT[this.type]);
}
MSFlyout.prototype.handleDeactivate = function() {
// Deactivate MSFlyout
if (this.type == MSFlyout.TYPE_METANAVLOGIN && !overMsNaviMeta && !hasInputFocus) {
this.active = false;
MSFlyout.popClassMN(this.flyout);
}
else{
this.active = false;
MSFlyout.popClass(this.flyout, MSFlyout.CSS_CLASS_HOVER);
}
}
// Helper Methods
function getAbsTop(element) {
if (element.offsetParent) {
return element.offsetTop + getAbsTop(element.offsetParent);
} else {
return element.offsetTop;
}
}