diff options
Diffstat (limited to 'httemplate/elements/xmenu.js')
| -rw-r--r-- | httemplate/elements/xmenu.js | 668 | 
1 files changed, 668 insertions, 0 deletions
| diff --git a/httemplate/elements/xmenu.js b/httemplate/elements/xmenu.js new file mode 100644 index 000000000..134265f53 --- /dev/null +++ b/httemplate/elements/xmenu.js @@ -0,0 +1,668 @@ +//<script> +/* + * This script was created by Erik Arvidsson (erik@eae.net) + * for WebFX (http://webfx.eae.net) + * Copyright 2001 + *  + * For usage see license at http://webfx.eae.net/license.html	 + * + * Created:		2001-01-12 + * Updates:		2001-11-20	Added hover mode support and removed Opera focus hacks + *				2001-12-20	Added auto positioning and some properties to support this + *				2002-08-13	toString used ' for attributes. Changed to " to allow in args + */ +  +// check browsers +var ua = navigator.userAgent; +var opera = /opera [56789]|opera\/[56789]/i.test(ua); +var ie = !opera && /MSIE/.test(ua); +var ie50 = ie && /MSIE 5\.[01234]/.test(ua); +var ie6 = ie && /MSIE [6789]/.test(ua); +var ieBox = ie && (document.compatMode == null || document.compatMode != "CSS1Compat"); +var moz = !opera && /gecko/i.test(ua); +var nn6 = !opera && /netscape.*6\./i.test(ua); +var khtml = /KHTML/i.test(ua); + +// define the default values + +webfxMenuDefaultWidth			= 154; + +webfxMenuDefaultBorderLeft		= 1; +webfxMenuDefaultBorderRight		= 1; +webfxMenuDefaultBorderTop		= 1; +webfxMenuDefaultBorderBottom	= 1; + +webfxMenuDefaultPaddingLeft		= 1; +webfxMenuDefaultPaddingRight	= 1; +webfxMenuDefaultPaddingTop		= 1; +webfxMenuDefaultPaddingBottom	= 1; + +webfxMenuDefaultShadowLeft		= 0; +webfxMenuDefaultShadowRight		= ie && !ie50 && /win32/i.test(navigator.platform) ? 4 :0; +webfxMenuDefaultShadowTop		= 0; +webfxMenuDefaultShadowBottom	= ie && !ie50 && /win32/i.test(navigator.platform) ? 4 : 0; + + +webfxMenuItemDefaultHeight		= 18; +webfxMenuItemDefaultText		= "Untitled"; +webfxMenuItemDefaultHref		= "javascript:void(0)"; + +webfxMenuSeparatorDefaultHeight	= 6; + +webfxMenuDefaultEmptyText		= "Empty"; + +webfxMenuDefaultUseAutoPosition	= nn6 ? false : true; + + + +// other global constants + +webfxMenuImagePath				= ""; + +webfxMenuUseHover				= opera ? true : false; +webfxMenuHideTime				= 500; +webfxMenuShowTime				= 200; + + + +var webFXMenuHandler = { +	idCounter		:	0, +	idPrefix		:	"webfx-menu-object-", +	all				:	{}, +	getId			:	function () { return this.idPrefix + this.idCounter++; }, +	overMenuItem	:	function (oItem) { +		if (this.showTimeout != null) +			window.clearTimeout(this.showTimeout); +		if (this.hideTimeout != null) +			window.clearTimeout(this.hideTimeout); +		var jsItem = this.all[oItem.id]; +		if (webfxMenuShowTime <= 0) +			this._over(jsItem); +		else if ( jsItem ) +			//this.showTimeout = window.setTimeout(function () { webFXMenuHandler._over(jsItem) ; }, webfxMenuShowTime); +			// I hate IE5.0 because the piece of shit crashes when using setTimeout with a function object +			this.showTimeout = window.setTimeout("webFXMenuHandler._over(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuShowTime); +	}, +	outMenuItem	:	function (oItem) { +		if (this.showTimeout != null) +			window.clearTimeout(this.showTimeout); +		if (this.hideTimeout != null) +			window.clearTimeout(this.hideTimeout); +		var jsItem = this.all[oItem.id]; +		if (webfxMenuHideTime <= 0) +			this._out(jsItem); +		else if ( jsItem )  +			//this.hideTimeout = window.setTimeout(function () { webFXMenuHandler._out(jsItem) ; }, webfxMenuHideTime); +			this.hideTimeout = window.setTimeout("webFXMenuHandler._out(webFXMenuHandler.all['" + jsItem.id + "'])", webfxMenuHideTime); +	}, +	blurMenu		:	function (oMenuItem) { +		window.setTimeout("webFXMenuHandler.all[\"" + oMenuItem.id + "\"].subMenu.hide();", webfxMenuHideTime); +	}, +	_over	:	function (jsItem) { +		if (jsItem.subMenu) { +			jsItem.parentMenu.hideAllSubs(); +			jsItem.subMenu.show(); +		} +		else +			jsItem.parentMenu.hideAllSubs(); +	}, +	_out	:	function (jsItem) { +		// find top most menu +		var root = jsItem; +		var m; +		if (root instanceof WebFXMenuButton) +			m = root.subMenu; +		else { +			m = jsItem.parentMenu; +			while (m.parentMenu != null && !(m.parentMenu instanceof WebFXMenuBar)) +				m = m.parentMenu; +		} +		if (m != null)	 +			m.hide();	 +	}, +	hideMenu	:	function (menu) { +		if (this.showTimeout != null) +			window.clearTimeout(this.showTimeout); +		if (this.hideTimeout != null) +			window.clearTimeout(this.hideTimeout); + +		this.hideTimeout = window.setTimeout("webFXMenuHandler.all['" + menu.id + "'].hide()", webfxMenuHideTime); +	}, +	showMenu	:	function (menu, src, dir) { +		if (this.showTimeout != null) +			window.clearTimeout(this.showTimeout); +		if (this.hideTimeout != null) +			window.clearTimeout(this.hideTimeout); + +		if (arguments.length < 3) +			dir = "vertical"; +		 +		menu.show(src, dir); +	} +}; + +function WebFXMenu() { +	this._menuItems	= []; +	this._subMenus	= []; +	this.id			= webFXMenuHandler.getId(); +	this.top		= 0; +	this.left		= 0; +	this.shown		= false; +	this.parentMenu	= null; +	webFXMenuHandler.all[this.id] = this; +} + +WebFXMenu.prototype.width			= webfxMenuDefaultWidth; +WebFXMenu.prototype.emptyText		= webfxMenuDefaultEmptyText; +WebFXMenu.prototype.useAutoPosition	= webfxMenuDefaultUseAutoPosition; + +WebFXMenu.prototype.borderLeft		= webfxMenuDefaultBorderLeft; +WebFXMenu.prototype.borderRight		= webfxMenuDefaultBorderRight; +WebFXMenu.prototype.borderTop		= webfxMenuDefaultBorderTop; +WebFXMenu.prototype.borderBottom	= webfxMenuDefaultBorderBottom; + +WebFXMenu.prototype.paddingLeft		= webfxMenuDefaultPaddingLeft; +WebFXMenu.prototype.paddingRight	= webfxMenuDefaultPaddingRight; +WebFXMenu.prototype.paddingTop		= webfxMenuDefaultPaddingTop; +WebFXMenu.prototype.paddingBottom	= webfxMenuDefaultPaddingBottom; + +WebFXMenu.prototype.shadowLeft		= webfxMenuDefaultShadowLeft; +WebFXMenu.prototype.shadowRight		= webfxMenuDefaultShadowRight; +WebFXMenu.prototype.shadowTop		= webfxMenuDefaultShadowTop; +WebFXMenu.prototype.shadowBottom	= webfxMenuDefaultShadowBottom; + + + +WebFXMenu.prototype.add = function (menuItem) { +	this._menuItems[this._menuItems.length] = menuItem; +	if (menuItem.subMenu) { +		this._subMenus[this._subMenus.length] = menuItem.subMenu; +		menuItem.subMenu.parentMenu = this; +	} +	 +	menuItem.parentMenu = this; +}; + +WebFXMenu.prototype.show = function (relObj, sDir) { +	if (this.useAutoPosition) +		this.position(relObj, sDir); + +	var divElement = document.getElementById(this.id); +	if ( divElement ) { + +	  divElement.style.left = opera ? this.left : this.left + "px"; +	  divElement.style.top = opera ? this.top : this.top + "px"; +	  divElement.style.visibility = "visible"; + +	  if ( ie ) { +	    var shimElement = document.getElementById(this.id + "Shim"); +	    if ( shimElement ) { +	      shimElement.style.width = divElement.offsetWidth; +	      shimElement.style.height = divElement.offsetHeight; +	      shimElement.style.top = divElement.style.top; +	      shimElement.style.left = divElement.style.left; +	      /*shimElement.style.zIndex = divElement.style.zIndex - 1; */ +	      shimElement.style.display = "block"; +	      shimElement.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'; +	    } +	  } + +	} + +	this.shown = true; + +	if (this.parentMenu) +		this.parentMenu.show(); +}; + +WebFXMenu.prototype.hide = function () { +	this.hideAllSubs(); +	var divElement = document.getElementById(this.id); +	if ( divElement ) { +	  divElement.style.visibility = "hidden"; +	  if ( ie ) { +	    var shimElement = document.getElementById(this.id + "Shim"); +	    if ( shimElement ) { +	      shimElement.style.display = "none"; +	    } +	  } +	} + +	this.shown = false; +}; + +WebFXMenu.prototype.hideAllSubs = function () { +	for (var i = 0; i < this._subMenus.length; i++) { +		if (this._subMenus[i].shown) +			this._subMenus[i].hide(); +	} +}; + +WebFXMenu.prototype.toString = function () { +	var top = this.top + this.borderTop + this.paddingTop; +	var str = "<div id='" + this.id + "' class='webfx-menu' style='" +  +	"width:" + (!ieBox  ? +		this.width - this.borderLeft - this.paddingLeft - this.borderRight - this.paddingRight  :  +		this.width) + "px;" + +	(this.useAutoPosition ? +		"left:" + this.left + "px;" + "top:" + this.top + "px;" : +		"") + +	(ie50 ? "filter: none;" : "") + +	"'>"; + +	if (this._menuItems.length == 0) { +		str +=	"<span class='webfx-menu-empty'>" + this.emptyText + "</span>"; +	} +	else {	 +		str += '<span class="webfx-menu-title" onmouseover="webFXMenuHandler.overMenuItem(this)"' + +			(webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + +			 '>' + this.emptyText + '</span>'; +        	// str += '<div id="' + this.id + '-title">' + this.emptyText + '</div>'; +		// loop through all menuItems +		for (var i = 0; i < this._menuItems.length; i++) { +			var mi = this._menuItems[i]; +			str += mi; +			if (!this.useAutoPosition) { +				if (mi.subMenu && !mi.subMenu.useAutoPosition) +					mi.subMenu.top = top - mi.subMenu.borderTop - mi.subMenu.paddingTop; +				top += mi.height; +			} +		} + +	} +	 +	str += "</div>"; + +	if ( ie ) { +          str += "<iframe id='" + this.id + "Shim' src='javascript:false;' scrolling='no' frameBorder='0' style='position:absolute; top:0px; left: 0px; display:none;'></iframe>"; +	} +	 +	for (var i = 0; i < this._subMenus.length; i++) { +		this._subMenus[i].left = this.left + this.width - this._subMenus[i].borderLeft; +		str += this._subMenus[i]; +	} +	 +	return str; +}; +// WebFXMenu.prototype.position defined later + +function WebFXMenuItem(sText, sHref, sToolTip, oSubMenu) { +	this.text = sText || webfxMenuItemDefaultText; +	this.href = (sHref == null || sHref == "") ? webfxMenuItemDefaultHref : sHref; +	this.subMenu = oSubMenu; +	if (oSubMenu) +		oSubMenu.parentMenuItem = this; +	this.toolTip = sToolTip; +	this.id = webFXMenuHandler.getId(); +	webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuItem.prototype.height = webfxMenuItemDefaultHeight; +WebFXMenuItem.prototype.toString = function () { +	return	"<a" + +			" id='" + this.id + "'" + +			" href=\"" + this.href + "\"" + +			(this.toolTip ? " title=\"" + this.toolTip + "\"" : "") + +			" onmouseover='webFXMenuHandler.overMenuItem(this)'" + +			(webfxMenuUseHover ? " onmouseout='webFXMenuHandler.outMenuItem(this)'" : "") + +			(this.subMenu ? " unselectable='on' tabindex='-1'" : "") + +			">" + +			(this.subMenu ? "<img class='arrow' src=\"" + webfxMenuImagePath + "arrow.right.black.png\">" : "") + +			this.text +  +			"</a>"; +}; + + +function WebFXMenuSeparator() { +	this.id = webFXMenuHandler.getId(); +	webFXMenuHandler.all[this.id] = this; +}; +WebFXMenuSeparator.prototype.height = webfxMenuSeparatorDefaultHeight; +WebFXMenuSeparator.prototype.toString = function () { +	return	"<div" + +			" id='" + this.id + "'" + +			(webfxMenuUseHover ?  +			" onmouseover='webFXMenuHandler.overMenuItem(this)'" + +			" onmouseout='webFXMenuHandler.outMenuItem(this)'" +			: +			"") + +			"></div>" +}; + +function WebFXMenuBar() { +	this._parentConstructor = WebFXMenu; +	this._parentConstructor(); +} +WebFXMenuBar.prototype = new WebFXMenu; +WebFXMenuBar.prototype.toString = function () { +	var str = "<div id='" + this.id + "' class='webfx-menu-bar'>"; +	 +	// loop through all menuButtons +	for (var i = 0; i < this._menuItems.length; i++) +		str += this._menuItems[i]; +	 +	str += "</div>"; + +	for (var i = 0; i < this._subMenus.length; i++) +		str += this._subMenus[i]; +	 +	return str; +}; + +function WebFXMenuButton(sText, sHref, sToolTip, oSubMenu) { +	this._parentConstructor = WebFXMenuItem; +	this._parentConstructor(sText, sHref, sToolTip, oSubMenu); +} +WebFXMenuButton.prototype = new WebFXMenuItem; +WebFXMenuButton.prototype.toString = function () { +	return	"<a" + +			" id='" + this.id + "'" + +			" href='" + this.href + "'" + +			(this.toolTip ? " title='" + this.toolTip + "'" : "") + +			(webfxMenuUseHover ? +				(" onmouseover='webFXMenuHandler.overMenuItem(this)'" + +				" onmouseout='webFXMenuHandler.outMenuItem(this)'") : +				( +					" onfocus='webFXMenuHandler.overMenuItem(this)'" + +					(this.subMenu ? +						" onblur='webFXMenuHandler.blurMenu(this)'" : +						"" +					) +				)) + +			">" + +			(this.subMenu ? "<img class='arrow' src='" + webfxMenuImagePath + "arrow.right.png'>" : "") +				 +			this.text +  +			"</a>"; +}; + + + + + +/* Position functions */ + + +function getInnerLeft(el) { + +	if (el == null) return 0; + +	if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + +	return parseInt( getLeft(el) + parseInt(getBorderLeft(el)) ); + +} + + + +function getLeft(el, debug) { + +	if (el == null) return 0; + +        //if ( debug ) +	//  alert ( el.offsetLeft + ' - ' + getInnerLeft(el.offsetParent) ); + +	return parseInt( el.offsetLeft + parseInt(getInnerLeft(el.offsetParent)) ); + +} + + + +function getInnerTop(el) { + +	if (el == null) return 0; + +	if (ieBox && el == document.body || !ieBox && el == document.documentElement) return 0; + +	return parseInt( getTop(el) + parseInt(getBorderTop(el)) ); + +} + + + +function getTop(el) { + +	if (el == null) return 0; + +	return parseInt( el.offsetTop + parseInt(getInnerTop(el.offsetParent)) ); + +} + + + +function getBorderLeft(el) { + +	return ie ? + +		el.clientLeft : + +		( khtml  +		    ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) +		    : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-left-width"))  +		); + +} + + + +function getBorderTop(el) { + +	return ie ? + +		el.clientTop : + +		( khtml  +		    ? parseInt(document.defaultView.getComputedStyle(el, null).getPropertyValue("border-left-width")) +		    : parseInt(window.getComputedStyle(el, null).getPropertyValue("border-top-width")) +		); + +} + + + +function opera_getLeft(el) { + +	if (el == null) return 0; + +	return el.offsetLeft + opera_getLeft(el.offsetParent); + +} + + + +function opera_getTop(el) { + +	if (el == null) return 0; + +	return el.offsetTop + opera_getTop(el.offsetParent); + +} + + + +function getOuterRect(el, debug) { + +	return { + +		left:	(opera ? opera_getLeft(el) : getLeft(el, debug)), + +		top:	(opera ? opera_getTop(el) : getTop(el)), + +		width:	el.offsetWidth, + +		height:	el.offsetHeight + +	}; + +} + + + +// mozilla bug! scrollbars not included in innerWidth/height + +function getDocumentRect(el) { + +	return { + +		left:	0, + +		top:	0, + +		width:	(ie ? + +					(ieBox ? document.body.clientWidth : document.documentElement.clientWidth) : + +					window.innerWidth + +				), + +		height:	(ie ? + +					(ieBox ? document.body.clientHeight : document.documentElement.clientHeight) : + +					window.innerHeight + +				) + +	}; + +} + + + +function getScrollPos(el) { + +	return { + +		left:	(ie ? + +					(ieBox ? document.body.scrollLeft : document.documentElement.scrollLeft) : + +					window.pageXOffset + +				), + +		top:	(ie ? + +					(ieBox ? document.body.scrollTop : document.documentElement.scrollTop) : + +					window.pageYOffset + +				) + +	}; + +} + + +/* end position functions */ + +WebFXMenu.prototype.position = function (relEl, sDir) { +	var dir = sDir; +	// find parent item rectangle, piRect +	var piRect; +	if (!relEl) { +		var pi = this.parentMenuItem; +		if (!this.parentMenuItem) +			return; +		 +		relEl = document.getElementById(pi.id); +		if (dir == null) +			dir = pi instanceof WebFXMenuButton ? "vertical" : "horizontal"; +		//alert('created RelEl from parent: ' + pi.id); +		piRect = getOuterRect(relEl, 1); +	} +	else if (relEl.left != null && relEl.top != null && relEl.width != null && relEl.height != null) {	// got a rect +		//alert('passed a Rect as RelEl: ' + typeof(relEl)); + +		piRect = relEl; +	} +	else { +		//alert('passed an element as RelEl: ' + typeof(relEl)); +		piRect = getOuterRect(relEl); +	} + +	var menuEl = document.getElementById(this.id); +	var menuRect = getOuterRect(menuEl); +	var docRect = getDocumentRect(); +	var scrollPos = getScrollPos(); +	var pMenu = this.parentMenu; +	 +	if (dir == "vertical") { +		if (piRect.left + menuRect.width - scrollPos.left <= docRect.width) { +			//alert('piRect.left: ' + piRect.left); +			this.left = piRect.left; +			if ( ! ie ) +			  this.left = this.left + 138; +		} else if (docRect.width >= menuRect.width) { +			//konq (not safari though) winds up here by accident and positions the menus all weird +			//alert('docRect.width + scrollPos.left - menuRect.width'); + +			this.left = docRect.width + scrollPos.left - menuRect.width; +		} else { +			//alert('scrollPos.left: ' + scrollPos.left); +			this.left = scrollPos.left; +		} +			 +		if (piRect.top + piRect.height + menuRect.height <= docRect.height + scrollPos.top) + +			this.top = piRect.top + piRect.height; + +		else if (piRect.top - menuRect.height >= scrollPos.top) + +			this.top = piRect.top - menuRect.height; + +		else if (docRect.height >= menuRect.height) + +			this.top = docRect.height + scrollPos.top - menuRect.height; + +		else + +			this.top = scrollPos.top; +	} +	else { +		if (piRect.top + menuRect.height - this.borderTop - this.paddingTop <= docRect.height + scrollPos.top) + +			this.top = piRect.top - this.borderTop - this.paddingTop; + +		else if (piRect.top + piRect.height - menuRect.height + this.borderTop + this.paddingTop >= 0) + +			this.top = piRect.top + piRect.height - menuRect.height + this.borderBottom + this.paddingBottom + this.shadowBottom; + +		else if (docRect.height >= menuRect.height) + +			this.top = docRect.height + scrollPos.top - menuRect.height; + +		else + +			this.top = scrollPos.top; + + + +		var pMenuPaddingLeft = pMenu ? pMenu.paddingLeft : 0; + +		var pMenuBorderLeft = pMenu ? pMenu.borderLeft : 0; + +		var pMenuPaddingRight = pMenu ? pMenu.paddingRight : 0; + +		var pMenuBorderRight = pMenu ? pMenu.borderRight : 0; + +		 + +		if (piRect.left + piRect.width + menuRect.width + pMenuPaddingRight + + +			pMenuBorderRight - this.borderLeft + this.shadowRight <= docRect.width + scrollPos.left) + +			this.left = piRect.left + piRect.width + pMenuPaddingRight + pMenuBorderRight - this.borderLeft; + +		else if (piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight >= 0) + +			this.left = piRect.left - menuRect.width - pMenuPaddingLeft - pMenuBorderLeft + this.borderRight + this.shadowRight; + +		else if (docRect.width >= menuRect.width) + +			this.left = docRect.width  + scrollPos.left - menuRect.width; + +		else + +			this.left = scrollPos.left; +	} +}; | 
