SVN Alba r4702 - prosistem/alba/trunk/alba/web/js/jsmenu
Author: ftoledo Date: 2007-06-04 16:20:56 -0300 (Mon, 04 Jun 2007) New Revision: 4702 Modified: prosistem/alba/trunk/alba/web/js/jsmenu/JSCookMenu.js Log: nueva version 2.03 del menu javascript Modified: prosistem/alba/trunk/alba/web/js/jsmenu/JSCookMenu.js =================================================================== --- prosistem/alba/trunk/alba/web/js/jsmenu/JSCookMenu.js 2007-06-04 19:14:49 UTC (rev 4701) +++ prosistem/alba/trunk/alba/web/js/jsmenu/JSCookMenu.js 2007-06-04 19:20:56 UTC (rev 4702) @@ -1,6 +1,8 @@ /* - JSCookMenu v1.4.4. (c) Copyright 2002-2005 by Heng Yuan + JSCookMenu v2.0.3 (c) Copyright 2002-2006 by Heng Yuan + http://jscook.sourceforge.net/JSCookMenu/ + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation @@ -20,22 +22,12 @@ DEALINGS IN THE SOFTWARE. */ -// Globals -var _cmIDCount = 0; -var _cmIDName = 'cmSubMenuID'; // for creating submenu id - -var _cmTimeOut = null; // how long the menu would stay -var _cmCurrentItem = null; // the current menu item being selected; - -var _cmNoAction = new Object (); // indicate that the item cannot be hovered. -var _cmNoClick = new Object (); // similar to _cmNoAction but does not respond to mouseup/mousedown events -var _cmSplit = new Object (); // indicate that the item is a menu split - -var _cmItemList = new Array (); // a simple list of items - // default node properties var _cmNodeProperties = { + // theme prefix + prefix: '', + // main menu display attributes // // Note. When the menu bar is horizontal, @@ -51,34 +43,162 @@ // HTML code to the left of the regular item mainItemLeft: '', // HTML code to the right of the regular item - mainItemRight: '', + mainItemRight: '', // sub menu display attributes // HTML code to the left of the folder item - folderLeft: '', + folderLeft: '', // HTML code to the right of the folder item - folderRight: '', + folderRight: '', // HTML code to the left of the regular item - itemLeft: '', + itemLeft: '', // HTML code to the right of the regular item - itemRight: '', + itemRight: '', // cell spacing for main menu - mainSpacing: 0, + mainSpacing: 0, // cell spacing for sub menus - subSpacing: 0, + subSpacing: 0, + + // optional settings + // If not set, use the default + // auto disappear time for submenus in milli-seconds - delay: 500, + delay: 500, + // 1st layer sub menu starting index + zIndexStart: 1000, + // z-index incremental step for subsequent layers + zIndexInc: 5, + + // sub menu header appears before the sub menu table + subMenuHeader: null, + // sub menu header appears after the sub menu table + subMenuFooter: null, + + // submenu location adjustments + // + // offsetHMainAdjust for adjusting the first submenu + // of a 'hbr' menu. + // offsetVMainAdjust for adjusting the first submenu + // of a 'vbr' menu. + // offsetSubAdjust for subsequent level of submenus + // + offsetHMainAdjust: [0, 0], + offsetVMainAdjust: [0, 0], + offsetSubAdjust: [0, 0], + // act on click to open sub menu // not yet implemented // 0 : use default behavior // 1 : hover open in all cases // 2 : click on main, hover on sub - // 3 : click open in all cases - clickOpen: 1 + // 3 : click open in all cases (illegal as of 1.5) + clickOpen: 1, + + // special effects on open/closing a sub menu + effect: null }; +// Globals +var _cmIDCount = 0; +var _cmIDName = 'cmSubMenuID'; // for creating submenu id + +var _cmTimeOut = null; // how long the menu would stay +var _cmCurrentItem = null; // the current menu item being selected; + +var _cmNoAction = new Object (); // indicate that the item cannot be hovered. +var _cmNoClick = new Object (); // similar to _cmNoAction but does not respond to mouseup/mousedown events +var _cmSplit = new Object (); // indicate that the item is a menu split + +var _cmMenuList = new Array (); // a list of the current menus +var _cmItemList = new Array (); // a simple list of items + +var _cmFrameList = new Array (); // a pool of reusable iframes +var _cmFrameListSize = 0; // keep track of the actual size +var _cmFrameIDCount = 0; // keep track of the frame id +var _cmFrameMasking = true; // use the frame masking + +// disable iframe masking for IE7 +/*@cc_on + @if (@_jscript_version >= 5.6) + if (_cmFrameMasking) + { + var v = navigator.appVersion; + var i = v.indexOf ("MSIE "); + if (i >= 0) + { + if (parseInt (navigator.appVersion.substring (i + 5)) >= 7) + _cmFrameMasking = false; + } + } + @end +@*/ + +var _cmClicked = false; // for onClick + +// flag for turning on off hiding objects +// +// 0: automatic +// 1: hiding +// 2: no hiding +var _cmHideObjects = 0; + +// Utility function to do a shallow copy a node property +function cmClone (nodeProperties) +{ + var returnVal = new Object (); + for (v in nodeProperties) + returnVal[v] = nodeProperties[v]; + return returnVal; +} + +// +// store the new menu information into a structure to retrieve it later +// +function cmAllocMenu (id, menu, orient, nodeProperties, prefix) +{ + var info = new Object (); + info.div = id; + info.menu = menu; + info.orient = orient; + info.nodeProperties = nodeProperties; + info.prefix = prefix; + var menuID = _cmMenuList.length; + _cmMenuList[menuID] = info; + return menuID; +} + +// +// request a frame +// +function cmAllocFrame () +{ + if (_cmFrameListSize > 0) + return cmGetObject (_cmFrameList[--_cmFrameListSize]); + var frameObj = document.createElement ('iframe'); + var id = _cmFrameIDCount++; + frameObj.id = 'cmFrame' + id; + frameObj.frameBorder = '0'; + frameObj.style.display = 'none'; + frameObj.src = 'javascript:false'; + document.body.appendChild (frameObj); + frameObj.style.filter = 'alpha(opacity=0)'; + frameObj.style.zIndex = 99; + frameObj.style.position = 'absolute'; + frameObj.style.border = '0'; + frameObj.scrolling = 'no'; + return frameObj; +} + +// +// make a frame resuable later +// +function cmFreeFrame (frameObj) +{ + _cmFrameList[_cmFrameListSize++] = frameObj.id; +} + ////////////////////////////////////////////////////////////////////// // // Drawing Functions and Utility Functions @@ -96,43 +216,42 @@ // // return the property string for the menu item // -function cmActionItem (item, prefix, isMain, idSub, orient, nodeProperties) +function cmActionItem (item, isMain, idSub, menuInfo, menuID) { - var clickOpen = _cmNodeProperties.clickOpen; - if (nodeProperties.clickOpen) - clickOpen = nodeProperties.clickOpen; - - // var index = _cmItemList.push (item) - 1; _cmItemList[_cmItemList.length] = item; var index = _cmItemList.length - 1; idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); - orient = '\'' + orient + '\''; - prefix = '\'' + prefix + '\''; + + var clickOpen = menuInfo.nodeProperties.clickOpen; var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain); + + var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index; + var returnStr; if (onClick) - returnStr = ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmousedown="cmItemMouseDownOpenSub (this,' + index + ',' + prefix + ',' + orient + ',' + idSub + ')"'; + returnStr = ' onmouseover="cmItemMouseOver(' + param + ',false)" onmousedown="cmItemMouseDownOpenSub (' + param + ')"'; else - returnStr = ' onmouseover="cmItemMouseOverOpenSub (this,' + prefix + ',' + isMain + ',' + idSub + ',' + orient + ',' + index + ')" onmousedown="cmItemMouseDown (this,' + index + ')"'; - return returnStr + ' onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')" onmouseup="cmItemMouseUp (this,' + index + ')"'; + returnStr = ' onmouseover="cmItemMouseOverOpenSub (' + param + ')" onmousedown="cmItemMouseDown (' + param + ')"'; + return returnStr + ' onmouseout="cmItemMouseOut (' + param + ')" onmouseup="cmItemMouseUp (' + param + ')"'; } // // this one is used by _cmNoClick to only take care of onmouseover and onmouseout // events which are associated with menu but not actions associated with menu clicking/closing // -function cmNoClickItem (item, prefix, isMain, idSub, orient, nodeProperties) +function cmNoClickItem (item, isMain, idSub, menuInfo, menuID) { // var index = _cmItemList.push (item) - 1; _cmItemList[_cmItemList.length] = item; var index = _cmItemList.length - 1; idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); - orient = '\'' + orient + '\''; - prefix = '\'' + prefix + '\''; - return ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')"'; + + var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index; + + return ' onmouseover="cmItemMouseOver (' + param + ')" onmouseout="cmItemMouseOut (' + param + ')"'; } -function cmNoActionItem (item, prefix) +function cmNoActionItem (item) { return item[1]; } @@ -156,9 +275,14 @@ // // draw the sub menu recursively // -function cmDrawSubMenu (subMenu, prefix, id, orient, nodeProperties) +function cmDrawSubMenu (subMenu, prefix, id, nodeProperties, zIndexStart, menuInfo, menuID) { - var str = '<div class="' + prefix + 'SubMenu" id="' + id + '"><table summary="sub menu" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">'; + var str = '<div class="' + prefix + 'SubMenu" id="' + id + '" style="z-index: ' + zIndexStart + ';position: absolute; top: 0px; left: 0px;">'; + if (nodeProperties.subMenuHeader) + str += nodeProperties.subMenuHeader; + + str += '<table summary="sub menu" id="' + id + 'Table" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">'; + var strSub = ''; var item; @@ -177,20 +301,22 @@ if (item == _cmSplit) item = cmSplitItem (prefix, 0, true); + item.parentItem = subMenu; + item.subMenuID = id; hasChild = (item.length > 5); idSub = hasChild ? cmNewID () : null; str += '<tr class="' + prefix + 'MenuItem"'; if (item[0] != _cmNoClick) - str += cmActionItem (item, prefix, 0, idSub, orient, nodeProperties); + str += cmActionItem (item, 0, idSub, menuInfo, menuID); else - str += cmNoClickItem (item, prefix, 0, idSub, orient, nodeProperties); + str += cmNoClickItem (item, 0, idSub, menuInfo, menuID); str += '>' if (item[0] == _cmNoAction || item[0] == _cmNoClick) { - str += cmNoActionItem (item, prefix); + str += cmNoActionItem (item); str += '</tr>'; continue; } @@ -212,56 +338,77 @@ if (hasChild) { str += nodeProperties.folderRight; - strSub += cmDrawSubMenu (item, prefix, idSub, orient, nodeProperties); + strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, zIndexStart + nodeProperties.zIndexInc, menuInfo, menuID); } else str += nodeProperties.itemRight; str += '</td></tr>'; } - str += '</table></div>' + strSub; + str += '</table>'; + + if (nodeProperties.subMenuFooter) + str += nodeProperties.subMenuFooter; + str += '</div>' + strSub; return str; } // // The function that builds the menu inside the specified element id. // -// @param id id of the element -// orient orientation of the menu in [hv][ab][lr] format -// menu the menu object to be drawn -// nodeProperties properties for each menu node +// id id of the element +// orient orientation of the menu in [hv][ub][lr] format +// menu the menu object to be drawn +// nodeProperties properties for the theme +// prefix prefix of the theme // function cmDraw (id, menu, orient, nodeProperties, prefix) { var obj = cmGetObject (id); + if (!prefix) + prefix = nodeProperties.prefix; + if (!prefix) + prefix = ''; if (!nodeProperties) nodeProperties = _cmNodeProperties; - if (!prefix) - prefix = ''; + if (!orient) + orient = 'hbr'; + var menuID = cmAllocMenu (id, menu, orient, nodeProperties, prefix); + var menuInfo = _cmMenuList[menuID]; + + // setup potentially missing properties + if (!nodeProperties.delay) + nodeProperties.delay = _cmNodeProperties.delay; + if (!nodeProperties.clickOpen) + nodeProperties.clickOpen = _cmNodeProperties.clickOpen; + if (!nodeProperties.zIndexStart) + nodeProperties.zIndexStart = _cmNodeProperties.zIndexStart; + if (!nodeProperties.zIndexInc) + nodeProperties.zIndexInc = _cmNodeProperties.zIndexInc; + if (!nodeProperties.offsetHMainAdjust) + nodeProperties.offsetHMainAdjust = _cmNodeProperties.offsetHMainAdjust; + if (!nodeProperties.offsetVMainAdjust) + nodeProperties.offsetVMainAdjust = _cmNodeProperties.offsetVMainAdjust; + if (!nodeProperties.offsetSubAdjust) + nodeProperties.offsetSubAdjust = _cmNodeProperties.offsetSubAdjust; + // save user setting on frame masking + menuInfo.cmFrameMasking = _cmFrameMasking; + var str = '<table summary="main menu" class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '">'; var strSub = ''; - if (!orient) - orient = 'hbr'; - - var orientStr = String (orient); - var orientSub; var vertical; // draw the main menu items - if (orientStr.charAt (0) == 'h') + if (orient.charAt (0) == 'h') { - // horizontal menu - orientSub = 'v' + orientStr.substr (1, 2); str += '<tr>'; vertical = false; } else { - // vertical menu - orientSub = 'v' + orientStr.substr (1, 2); vertical = true; } @@ -279,20 +426,23 @@ if (!item) continue; + item.menu = menu; + item.subMenuID = id; + str += vertical ? '<tr' : '<td'; str += ' class="' + prefix + 'MainItem"'; hasChild = (item.length > 5); idSub = hasChild ? cmNewID () : null; - str += cmActionItem (item, prefix, 1, idSub, orient, nodeProperties) + '>'; + str += cmActionItem (item, 1, idSub, menuInfo, menuID) + '>'; if (item == _cmSplit) item = cmSplitItem (prefix, 1, vertical); if (item[0] == _cmNoAction || item[0] == _cmNoClick) { - str += cmNoActionItem (item, prefix); + str += cmNoActionItem (item); str += vertical? '</tr>' : '</td>'; continue; } @@ -322,13 +472,12 @@ str += vertical ? '</tr>' : '</td>'; if (hasChild) - strSub += cmDrawSubMenu (item, prefix, idSub, orientSub, nodeProperties); + strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, nodeProperties.zIndexStart, menuInfo, menuID); } if (!vertical) str += '</tr>'; str += '</table>' + strSub; obj.innerHTML = str; - //document.write ("<xmp>" + str + "</xmp>"); } // @@ -359,8 +508,11 @@ var menu = null; for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) { - if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'ul') + if (!currentDomItem.tagName) continue; + var tag = currentDomItem.tagName.toLowerCase (); + if (tag != 'ul' && tag != 'ol') + continue; menu = cmDrawFromTextSubMenu (currentDomItem); break; } @@ -385,38 +537,75 @@ } var item = new Array (); var currentItem = currentDomItem.firstChild; + var hasAction = false; for (; currentItem; currentItem = currentItem.nextSibling) { - // scan for span tag - if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'span') + // scan for span or div tag + if (!currentItem.tagName) continue; + if (currentItem.className == 'cmNoClick') + { + item[0] = _cmNoClick; + item[1] = getActionHTML (currentItem); + hasAction = true; + break; + } + if (currentItem.className == 'cmNoAction') + { + item[0] = _cmNoAction; + item[1] = getActionHTML (currentItem); + hasAction = true; + break; + } + var tag = currentItem.tagName.toLowerCase (); + if (tag != 'span') + continue; if (!currentItem.firstChild) item[0] = null; else item[0] = currentItem.innerHTML; + currentItem = currentItem.nextSibling; break; } + if (hasAction) + { + items[items.length] = item; + continue; + } if (!currentItem) continue; for (; currentItem; currentItem = currentItem.nextSibling) { - // scan for span tag - if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'a') + if (!currentItem.tagName) continue; - item[1] = currentItem.innerHTML; - item[2] = currentItem.href; - item[3] = currentItem.target; - item[4] = currentItem.title; - if (item[4] == '') + var tag = currentItem.tagName.toLowerCase (); + if (tag == 'a') + { + item[1] = currentItem.innerHTML; + item[2] = currentItem.href; + item[3] = currentItem.target; + item[4] = currentItem.title; + if (item[4] == '') + item[4] = null; + } + else if (tag == 'span' || tag == 'div') + { + item[1] = currentItem.innerHTML; + item[2] = null; + item[3] = null; item[4] = null; + } break; } for (; currentItem; currentItem = currentItem.nextSibling) { // scan for span tag - if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'ul') + if (!currentItem.tagName) continue; + var tag = currentItem.tagName.toLowerCase (); + if (tag != 'ul' && tag != 'ol') + continue; var subMenuItems = cmDrawFromTextSubMenu (currentItem); for (i = 0; i < subMenuItems.length; ++i) item[i + 5] = subMenuItems[i]; @@ -427,6 +616,116 @@ return items; } +// +// obtain the actual action item's action, which is inside a +// table. The first row should be it +// +function getActionHTML (htmlNode) +{ + var returnVal = '<td></td><td></td><td></td>'; + var currentDomItem; + // find the table first + for (currentDomItem = htmlNode.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) + { + if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'table') + break; + } + if (!currentDomItem) + return returnVal; + // skip over tbody + for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) + { + if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tbody') + break; + } + if (!currentDomItem) + return returnVal; + // get the first tr + for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) + { + if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tr') + break; + } + if (!currentDomItem) + return returnVal; + return currentDomItem.innerHTML; +} + +// +// get the DOM object associated with the item +// +function cmGetMenuItem (item) +{ + if (!item.subMenuID) + return null; + var subMenu = cmGetObject (item.subMenuID); + // we are dealing with a main menu item + if (item.menu) + { + var menu = item.menu; + // skip over table, tbody, tr, reach td + subMenu = subMenu.firstChild.firstChild.firstChild.firstChild; + var i; + for (i = 0; i < menu.length; ++i) + { + if (menu[i] == item) + return subMenu; + subMenu = subMenu.nextSibling; + } + } + else if (item.parentItem) // sub menu item + { + var menu = item.parentItem; + var table = cmGetObject (item.subMenuID + 'Table'); + if (!table) + return null; + // skip over table, tbody, reach tr + subMenu = table.firstChild.firstChild; + var i; + for (i = 5; i < menu.length; ++i) + { + if (menu[i] == item) + return subMenu; + subMenu = subMenu.nextSibling; + } + } + return null; +} + +// +// disable a menu item +// +function cmDisableItem (item, prefix) +{ + if (!item) + return; + var menuItem = cmGetMenuItem (item); + if (!menuItem) + return; + if (item.menu) + menuItem.className = prefix + 'MainItemDisabled'; + else + menuItem.className = prefix + 'MenuItemDisabled'; + item.isDisabled = true; +} + +// +// enable a menu item +// +function cmEnableItem (item, prefix) +{ + if (!item) + return; + var menuItem = cmGetMenuItem (item); + if (!menuItem) + return; + if (item.menu) + menu.className = prefix + 'MainItem'; + else + menu.className = prefix + 'MenuItem'; + item.isDisabled = true; +} + ////////////////////////////////////////////////////////////////////// // // Mouse Event Handling Functions @@ -438,13 +737,24 @@ // // Here we just do things concerning this menu item, w/o opening sub menus. // -function cmItemMouseOver (obj, prefix, isMain, idSub, index) +function cmItemMouseOver (obj, isMain, idSub, menuID, index, calledByOpenSub) { + if (!calledByOpenSub && _cmClicked) + { + cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index); + return; + } + clearTimeout (_cmTimeOut); - if (!obj.cmPrefix) + if (_cmItemList[index].isDisabled) + return; + + var prefix = _cmMenuList[menuID].prefix; + + if (!obj.cmMenuID) { - obj.cmPrefix = prefix; + obj.cmMenuID = menuID; obj.cmIsMain = isMain; } @@ -477,7 +787,8 @@ return; } - var thatPrefix = _cmCurrentItem.cmPrefix; + var thatMenuInfo = _cmMenuList[_cmCurrentItem.cmMenuID]; + var thatPrefix = thatMenuInfo.prefix; var thatMenu = cmGetThisMenu (_cmCurrentItem, thatPrefix); if (thatMenu != thisMenu.cmParentMenu) @@ -487,7 +798,7 @@ else _cmCurrentItem.className = thatPrefix + 'MenuItem'; if (thatMenu.id != idSub) - cmHideMenu (thatMenu, thisMenu, thatPrefix); + cmHideMenu (thatMenu, thisMenu, thatMenuInfo); } } @@ -516,24 +827,31 @@ // // This function also opens sub menu // -function cmItemMouseOverOpenSub (obj, prefix, isMain, idSub, orient, index) +function cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index) { - cmItemMouseOver (obj, prefix, isMain, idSub, index); + clearTimeout (_cmTimeOut); + if (_cmItemList[index].isDisabled) + return; + + cmItemMouseOver (obj, isMain, idSub, menuID, index, true); + if (idSub) { var subMenu = cmGetObject (idSub); - cmShowSubMenu (obj, prefix, subMenu, orient); + var menuInfo = _cmMenuList[menuID]; + var orient = menuInfo.orient; + var prefix = menuInfo.prefix; + cmShowSubMenu (obj, isMain, subMenu, menuInfo); } } // // action should be taken for mouse moving out of the menu item // -function cmItemMouseOut (obj, delayTime) +function cmItemMouseOut (obj, isMain, idSub, menuID, index) { - if (!delayTime) - delayTime = _cmNodeProperties.delay; + var delayTime = _cmMenuList[menuID].nodeProperties.delay; _cmTimeOut = window.setTimeout ('cmHideMenuTime ()', delayTime); window.defaultStatus = ''; } @@ -541,14 +859,18 @@ // // action should be taken for mouse button down at a menu item // -function cmItemMouseDown (obj, index) +function cmItemMouseDown (obj, isMain, idSub, menuID, index) { + if (_cmItemList[index].isDisabled) + return; + if (cmIsDefaultItem (_cmItemList[index])) { + var prefix = _cmMenuList[menuID].prefix; if (obj.cmIsMain) - obj.className = obj.cmPrefix + 'MainItemActive'; + obj.className = prefix + 'MainItemActive'; else - obj.className = obj.cmPrefix + 'MenuItemActive'; + obj.className = prefix + 'MenuItemActive'; } } @@ -556,22 +878,30 @@ // action should be taken for mouse button down at a menu item // this is one also opens submenu if needed // -function cmItemMouseDownOpenSub (obj, index, prefix, orient, idSub) +function cmItemMouseDownOpenSub (obj, isMain, idSub, menuID, index) { - cmItemMouseDown (obj, index); + if (_cmItemList[index].isDisabled) + return; + _cmClicked = true; + cmItemMouseDown (obj, isMain, idSub, menuID, index); + if (idSub) { var subMenu = cmGetObject (idSub); - cmShowSubMenu (obj, prefix, subMenu, orient); + var menuInfo = _cmMenuList[menuID]; + cmShowSubMenu (obj, isMain, subMenu, menuInfo); } } // // action should be taken for mouse button up at a menu item // -function cmItemMouseUp (obj, index) +function cmItemMouseUp (obj, isMain, idSub, menuID, index) { + if (_cmItemList[index].isDisabled) + return; + var item = _cmItemList[index]; var link = null, target = '_self'; @@ -583,10 +913,12 @@ if (link != null) { + _cmClicked = false; window.open (link, target); } - var prefix = obj.cmPrefix; + var menuInfo = _cmMenuList[menuID]; + var prefix = menuInfo.prefix; var thisMenu = cmGetThisMenu (obj, prefix); var hasChild = (item.length > 5); @@ -599,7 +931,7 @@ else obj.className = prefix + 'MenuItem'; } - cmHideMenu (thisMenu, null, prefix); + cmHideMenu (thisMenu, null, menuInfo); } else { @@ -622,12 +954,25 @@ // // move submenu to the appropriate location // -// @param obj the menu item that opens up the subMenu -// subMenu the sub menu to be shown -// orient the orientation of the subMenu -// -function cmMoveSubMenu (obj, subMenu, orient) +function cmMoveSubMenu (obj, isMain, subMenu, menuInfo) { + var orient = menuInfo.orient; + + var offsetAdjust; + + if (isMain) + { + if (orient.charAt (0) == 'h') + offsetAdjust = menuInfo.nodeProperties.offsetHMainAdjust; + else + offsetAdjust = menuInfo.nodeProperties.offsetVMainAdjust; + } + else + offsetAdjust = menuInfo.nodeProperties.offsetSubAdjust; + + if (!isMain && orient.charAt (0) == 'h') + orient = 'v' + orient.charAt (1) + orient.charAt (2); + var mode = String (orient); var p = subMenu.offsetParent; var subMenuWidth = cmGetWidth (subMenu); @@ -635,25 +980,50 @@ if (mode.charAt (0) == 'h') { if (mode.charAt (1) == 'b') - subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj)) + 'px'; + subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) + offsetAdjust[1]) + 'px'; else - subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu)) + 'px'; + subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu) - offsetAdjust[1]) + 'px'; if (horiz == 'r') - subMenu.style.left = (cmGetXAt (obj, p)) + 'px'; + subMenu.style.left = (cmGetXAt (obj, p) + offsetAdjust[0]) + 'px'; else - subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth) + 'px'; + subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth - offsetAdjust[0]) + 'px'; } else { if (horiz == 'r') - subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj)) + 'px'; + subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) + offsetAdjust[0]) + 'px'; else - subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth) + 'px'; + subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth - offsetAdjust[0]) + 'px'; if (mode.charAt (1) == 'b') - subMenu.style.top = (cmGetYAt (obj, p)) + 'px'; + subMenu.style.top = (cmGetYAt (obj, p) + offsetAdjust[1]) + 'px'; else - subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu)) + 'px'; + subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu) + offsetAdjust[1]) + 'px'; } + + // IE specific iframe masking method + /*@cc_on + @if (@_jscript_version >= 5.5) + if (menuInfo.cmFrameMasking) + { + if (!subMenu.cmFrameObj) + { + var frameObj = cmAllocFrame (); + subMenu.cmFrameObj = frameObj; + } + + var frameObj = subMenu.cmFrameObj; + frameObj.style.zIndex = subMenu.style.zIndex - 1; + frameObj.style.left = (cmGetX (subMenu) - cmGetX (frameObj.offsetParent)) + 'px'; + frameObj.style.top = (cmGetY (subMenu) - cmGetY (frameObj.offsetParent)) + 'px'; + frameObj.style.width = cmGetWidth (subMenu) + 'px'; + frameObj.style.height = cmGetHeight (subMenu) + 'px'; + frameObj.style.display = 'block'; + } + @end + @*/ + if (horiz != orient.charAt (2)) + orient = orient.charAt (0) + orient.charAt (1) + horiz; + return orient; } // @@ -703,12 +1073,10 @@ // show the subMenu w/ specified orientation // also move it to the correct coordinates // -// @param obj the menu item that opens up the subMenu -// subMenu the sub menu to be shown -// orient the orientation of the subMenu -// -function cmShowSubMenu (obj, prefix, subMenu, orient) +function cmShowSubMenu (obj, isMain, subMenu, menuInfo) { + var prefix = menuInfo.prefix; + if (!subMenu.cmParentMenu) { // establish the tree w/ back edge @@ -716,35 +1084,68 @@ subMenu.cmParentMenu = thisMenu; if (!thisMenu.cmSubMenu) thisMenu.cmSubMenu = new Array (); - //thisMenu.cmSubMenu.push (subMenu); thisMenu.cmSubMenu[thisMenu.cmSubMenu.length] = subMenu; } - // position the sub menu - cmMoveSubMenu (obj, subMenu, orient); - subMenu.style.visibility = 'visible'; + var effectInstance = subMenu.cmEffect; + if (effectInstance) + effectInstance.showEffect (true); + else + { + // position the sub menu only if we are not already showing the submenu + var orient = cmMoveSubMenu (obj, isMain, subMenu, menuInfo); + subMenu.cmOrient = orient; - // - // On IE, controls such as SELECT, OBJECT, IFRAME (before 5.5) - // are window based controls. So, if the sub menu and these - // controls overlap, sub menu would be hidden behind them. Thus - // one needs to turn the visibility of these controls off when the - // sub menu is showing, and turn their visibility back on - // when the sub menu is hiding. - // - if (document.all) // it is IE + var forceShow = false; + if (subMenu.style.visibility != 'visible' && menuInfo.nodeProperties.effect) + { + try + { + effectInstance = menuInfo.nodeProperties.effect.getInstance (subMenu, orient); + effectInstance.showEffect (false); + } + catch (e) + { + forceShow = true; + subMenu.cmEffect = null; + } + } + else + forceShow = true; + + if (forceShow) + { + subMenu.style.visibility = 'visible'; + /*@cc_on + @if (@_jscript_version >= 5.5) + if (subMenu.cmFrameObj) + subMenu.cmFrameObj.style.display = 'block'; + @end + @*/ + } + } + + if (!_cmHideObjects) { - /* part of Felix Zaslavskiy's fix on hiding controls - not really sure if this part is necessary, but shouldn't - hurt. */ + _cmHideObjects = 2; // default = not hide, may change behavior later + try + { + if (window.opera) + { + if (parseInt (navigator.appVersion) < 9) + _cmHideObjects = 1; + } + } + catch (e) + { + } + } + + if (_cmHideObjects == 1) + { if (!subMenu.cmOverlap) subMenu.cmOverlap = new Array (); -/*@cc_on @*/ -/*@if (@_jscript_version >= 5.5) -@else @*/ cmHideControl ("IFRAME", subMenu); -/*@end @*/ - cmHideControl ("SELECT", subMenu); cmHideControl ("OBJECT", subMenu); } } @@ -762,6 +1163,16 @@ for (i = 0; i < items.length; ++i) { if (items[i].cmIsMain) + { + if (items[i].className == (prefix + 'MainItemDisabled')) + continue; + } + else + { + if (items[i].className == (prefix + 'MenuItemDisabled')) + continue; + } + if (items[i].cmIsMain) str = prefix + 'MainItem'; else str = prefix + 'MenuItem'; @@ -776,21 +1187,57 @@ // function cmHideMenuTime () { + _cmClicked = false; if (_cmCurrentItem) { - var prefix = _cmCurrentItem.cmPrefix; - cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, prefix); + var menuInfo = _cmMenuList[_cmCurrentItem.cmMenuID]; + var prefix = menuInfo.prefix; + cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, menuInfo); _cmCurrentItem = null; } } // +// Only hides this menu +// +function cmHideThisMenu (thisMenu, menuInfo) +{ + var effectInstance = thisMenu.cmEffect; + if (effectInstance) + effectInstance.hideEffect (true); + else + { + thisMenu.style.visibility = 'hidden'; + thisMenu.style.top = '0px'; + thisMenu.style.left = '0px'; + thisMenu.cmOrient = null; + /*@cc_on + @if (@_jscript_version >= 5.5) + if (thisMenu.cmFrameObj) + { + var frameObj = thisMenu.cmFrameObj; + frameObj.style.display = 'none'; + frameObj.style.width = '1px'; + frameObj.style.height = '1px'; + thisMenu.cmFrameObj = null; + cmFreeFrame (frameObj); + } + @end + @*/ + } + + cmShowControl (thisMenu); + thisMenu.cmItems = null; +} + +// // hide thisMenu, children of thisMenu, as well as the ancestor // of thisMenu until currentMenu is encountered. currentMenu // will not be hidden // -function cmHideMenu (thisMenu, currentMenu, prefix) +function cmHideMenu (thisMenu, currentMenu, menuInfo) { + var prefix = menuInfo.prefix; var str = prefix + 'SubMenu'; // hide the down stream menus @@ -799,7 +1246,7 @@ var i; for (i = 0; i < thisMenu.cmSubMenu.length; ++i) { - cmHideSubMenu (thisMenu.cmSubMenu[i], prefix); + cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo); } } @@ -809,8 +1256,7 @@ cmResetMenu (thisMenu, prefix); if (thisMenu.className == str) { - thisMenu.style.visibility = 'hidden'; - cmShowControl (thisMenu); + cmHideThisMenu (thisMenu, menuInfo); } else break; @@ -822,7 +1268,7 @@ // hide thisMenu as well as its sub menus if thisMenu is not // already hidden // -function cmHideSubMenu (thisMenu, prefix) +function cmHideSubMenu (thisMenu, menuInfo) { if (thisMenu.style.visibility == 'hidden') return; @@ -831,12 +1277,12 @@ var i; for (i = 0; i < thisMenu.cmSubMenu.length; ++i) { - cmHideSubMenu (thisMenu.cmSubMenu[i], prefix); + cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo); } } + var prefix = menuInfo.prefix; cmResetMenu (thisMenu, prefix); - thisMenu.style.visibility = 'hidden'; - cmShowControl (thisMenu); + cmHideThisMenu (thisMenu, menuInfo); } // @@ -872,12 +1318,12 @@ // submenu then we dont want to put it on overlap list of // of a submenu a second time. // - bug fixed by Felix Zaslavskiy - if(obj.style.visibility == "hidden") + if(obj.style.visibility == 'hidden') continue; //subMenu.cmOverlap.push (obj); subMenu.cmOverlap[subMenu.cmOverlap.length] = obj; - obj.style.visibility = "hidden"; + obj.style.visibility = 'hidden'; } } @@ -913,6 +1359,35 @@ } // +// A special effect function to hook the menu which contains +// special effect object to the timer. +// +function cmTimeEffect (menuID, show, delayTime) +{ + window.setTimeout ('cmCallEffect("' + menuID + '",' + show + ')', delayTime); +} + +// +// A special effect function. Called by timer. +// +function cmCallEffect (menuID, show) +{ + var menu = cmGetObject (menuID); + if (!menu || !menu.cmEffect) + return; + try + { + if (show) + menu.cmEffect.showEffect (false); + else + menu.cmEffect.hideEffect (false); + } + catch (e) + { + } +} + +// // return true if this item is handled using default handlers // function cmIsDefaultItem (item) @@ -968,6 +1443,8 @@ // function cmGetX (obj) { + if (!obj) + return 0; var x = 0; do @@ -995,6 +1472,8 @@ function cmGetY (obj) { + if (!obj) + return 0; var y = 0; do { @@ -1039,7 +1518,6 @@ // // extract description from the menu item and set the status text -// @param item the menu item // function cmSetStatus (item) { @@ -1069,6 +1547,40 @@ return msg; } +/* v2.0.3 1. Fix an issue with IE6 displaying menu over HTTPS connection. + Thanks to Paul Horton for reporting the bug and testing + possible solutions. */ +/* v2.0.2 1. Minor clean up and some attempts to reduce memory leak in IE. */ +/* v2.0.1 1. Disable iframe masking for IE7 since it is no longer necessary. */ +/* v2.0 1. improves the way handling flash/iframe/select boxes in IE + and firefox and Opera 9. Hiding these elements is no + longer necessary. For older versions of Opera, flash/iframe + still need to be hidden. + 2. Improves cmDrawFromText (). Also allows custom actions. + 3. Improves clickOpen behavior. Now once a submenu is opened, + opening other sub menus no longer requires clicking. + 4. Special Effects. This version has hooks that allow people + to install special effects to various themes. + 5. For a given menu item, cmGetMenuitem(item) provides the ability + to find the corresponding DOM element. + 6. Disable API. If you know which item to disable, you can call + cmDisableItem(item, themePrefix) and cmEnableItem(item, themePrefix). + However, you will have to provide your own CSS for the item. + For purposes other than to disable an item, cmGetMenuItem (item) + is provided for locating HTML DOM element of the menu item in concern. + 7. Better z-index. Now you can specify in the theme property the + starting z-index and incremental step for submenus. + 8. Allow themes to insert additional elements before and after + the sub menu table. + 9. Improved themes. More organized and easier to customize. + 10. Add a flag to control hiding/nohiding objects/iframes. By default, + only Opera before 9 hides objects. + 11. Add new property options to control submenu positions to fine tune + the look. + 12. It is no longer necessary to specify the theme name while calling + cmDraw and cmDrawFromText. Currently it still accepts it, but it + will not in the future. +*/ /* v1.4.4 1. a quick fix for a bug for _cmSplit checking. reported by Son Nguyen. */
participants (1)
-
commits@pressenter.com.ar