| [ Index ] | PHP Cross Reference of Mambo 4.6.5 |
|
| [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 /* 2 JSCookMenu v2.0.3 (c) Copyright 2002-2006 by Heng Yuan 3 4 http://jscook.sourceforge.net/JSCookMenu/ 5 6 Permission is hereby granted, free of charge, to any person obtaining a 7 copy of this software and associated documentation files (the "Software"), 8 to deal in the Software without restriction, including without limitation 9 the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 and/or sell copies of the Software, and to permit persons to whom the 11 Software is furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included 14 in all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 DEALINGS IN THE SOFTWARE. 23 */ 24 25 // default node properties 26 var _cmNodeProperties = 27 { 28 // theme prefix 29 prefix: '', 30 31 // main menu display attributes 32 // 33 // Note. When the menu bar is horizontal, 34 // mainFolderLeft and mainFolderRight are 35 // put in <span></span>. When the menu 36 // bar is vertical, they would be put in 37 // a separate TD cell. 38 39 // HTML code to the left of the folder item 40 mainFolderLeft: '', 41 // HTML code to the right of the folder item 42 mainFolderRight: '', 43 // HTML code to the left of the regular item 44 mainItemLeft: '', 45 // HTML code to the right of the regular item 46 mainItemRight: '', 47 48 // sub menu display attributes 49 50 // HTML code to the left of the folder item 51 folderLeft: '', 52 // HTML code to the right of the folder item 53 folderRight: '', 54 // HTML code to the left of the regular item 55 itemLeft: '', 56 // HTML code to the right of the regular item 57 itemRight: '', 58 // cell spacing for main menu 59 mainSpacing: 0, 60 // cell spacing for sub menus 61 subSpacing: 0, 62 63 // optional settings 64 // If not set, use the default 65 66 // auto disappear time for submenus in milli-seconds 67 delay: 500, 68 69 // 1st layer sub menu starting index 70 zIndexStart: 1000, 71 // z-index incremental step for subsequent layers 72 zIndexInc: 5, 73 74 // sub menu header appears before the sub menu table 75 subMenuHeader: null, 76 // sub menu header appears after the sub menu table 77 subMenuFooter: null, 78 79 // submenu location adjustments 80 // 81 // offsetHMainAdjust for adjusting the first submenu 82 // of a 'hbr' menu. 83 // offsetVMainAdjust for adjusting the first submenu 84 // of a 'vbr' menu. 85 // offsetSubAdjust for subsequent level of submenus 86 // 87 offsetHMainAdjust: [0, 0], 88 offsetVMainAdjust: [0, 0], 89 offsetSubAdjust: [0, 0], 90 91 // act on click to open sub menu 92 // not yet implemented 93 // 0 : use default behavior 94 // 1 : hover open in all cases 95 // 2 : click on main, hover on sub 96 // 3 : click open in all cases (illegal as of 1.5) 97 clickOpen: 1, 98 99 // special effects on open/closing a sub menu 100 effect: null 101 }; 102 103 // Globals 104 var _cmIDCount = 0; 105 var _cmIDName = 'cmSubMenuID'; // for creating submenu id 106 107 var _cmTimeOut = null; // how long the menu would stay 108 var _cmCurrentItem = null; // the current menu item being selected; 109 110 var _cmNoAction = new Object (); // indicate that the item cannot be hovered. 111 var _cmNoClick = new Object (); // similar to _cmNoAction but does not respond to mouseup/mousedown events 112 var _cmSplit = new Object (); // indicate that the item is a menu split 113 114 var _cmMenuList = new Array (); // a list of the current menus 115 var _cmItemList = new Array (); // a simple list of items 116 117 var _cmFrameList = new Array (); // a pool of reusable iframes 118 var _cmFrameListSize = 0; // keep track of the actual size 119 var _cmFrameIDCount = 0; // keep track of the frame id 120 var _cmFrameMasking = true; // use the frame masking 121 122 // disable iframe masking for IE7 123 /*@cc_on 124 @if (@_jscript_version >= 5.6) 125 if (_cmFrameMasking) 126 { 127 var v = navigator.appVersion; 128 var i = v.indexOf ("MSIE "); 129 if (i >= 0) 130 { 131 if (parseInt (navigator.appVersion.substring (i + 5)) >= 7) 132 _cmFrameMasking = false; 133 } 134 } 135 @end 136 @*/ 137 138 var _cmClicked = false; // for onClick 139 140 // flag for turning on off hiding objects 141 // 142 // 0: automatic 143 // 1: hiding 144 // 2: no hiding 145 var _cmHideObjects = 0; 146 147 // Utility function to do a shallow copy a node property 148 function cmClone (nodeProperties) 149 { 150 var returnVal = new Object (); 151 for (v in nodeProperties) 152 returnVal[v] = nodeProperties[v]; 153 return returnVal; 154 } 155 156 // 157 // store the new menu information into a structure to retrieve it later 158 // 159 function cmAllocMenu (id, menu, orient, nodeProperties, prefix) 160 { 161 var info = new Object (); 162 info.div = id; 163 info.menu = menu; 164 info.orient = orient; 165 info.nodeProperties = nodeProperties; 166 info.prefix = prefix; 167 var menuID = _cmMenuList.length; 168 _cmMenuList[menuID] = info; 169 return menuID; 170 } 171 172 // 173 // request a frame 174 // 175 function cmAllocFrame () 176 { 177 if (_cmFrameListSize > 0) 178 return cmGetObject (_cmFrameList[--_cmFrameListSize]); 179 var frameObj = document.createElement ('iframe'); 180 var id = _cmFrameIDCount++; 181 frameObj.id = 'cmFrame' + id; 182 frameObj.frameBorder = '0'; 183 frameObj.style.display = 'none'; 184 frameObj.src = 'javascript:false'; 185 document.body.appendChild (frameObj); 186 frameObj.style.filter = 'alpha(opacity=0)'; 187 frameObj.style.zIndex = 99; 188 frameObj.style.position = 'absolute'; 189 frameObj.style.border = '0'; 190 frameObj.scrolling = 'no'; 191 return frameObj; 192 } 193 194 // 195 // make a frame resuable later 196 // 197 function cmFreeFrame (frameObj) 198 { 199 _cmFrameList[_cmFrameListSize++] = frameObj.id; 200 } 201 202 ////////////////////////////////////////////////////////////////////// 203 // 204 // Drawing Functions and Utility Functions 205 // 206 ////////////////////////////////////////////////////////////////////// 207 208 // 209 // produce a new unique id 210 // 211 function cmNewID () 212 { 213 return _cmIDName + (++_cmIDCount); 214 } 215 216 // 217 // return the property string for the menu item 218 // 219 function cmActionItem (item, isMain, idSub, menuInfo, menuID) 220 { 221 _cmItemList[_cmItemList.length] = item; 222 var index = _cmItemList.length - 1; 223 idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); 224 225 var clickOpen = menuInfo.nodeProperties.clickOpen; 226 var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain); 227 228 var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index; 229 230 var returnStr; 231 if (onClick) 232 returnStr = ' onmouseover="cmItemMouseOver(' + param + ',false)" onmousedown="cmItemMouseDownOpenSub (' + param + ')"'; 233 else 234 returnStr = ' onmouseover="cmItemMouseOverOpenSub (' + param + ')" onmousedown="cmItemMouseDown (' + param + ')"'; 235 return returnStr + ' onmouseout="cmItemMouseOut (' + param + ')" onmouseup="cmItemMouseUp (' + param + ')"'; 236 } 237 238 // 239 // this one is used by _cmNoClick to only take care of onmouseover and onmouseout 240 // events which are associated with menu but not actions associated with menu clicking/closing 241 // 242 function cmNoClickItem (item, isMain, idSub, menuInfo, menuID) 243 { 244 // var index = _cmItemList.push (item) - 1; 245 _cmItemList[_cmItemList.length] = item; 246 var index = _cmItemList.length - 1; 247 idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); 248 249 var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index; 250 251 return ' onmouseover="cmItemMouseOver (' + param + ')" onmouseout="cmItemMouseOut (' + param + ')"'; 252 } 253 254 function cmNoActionItem (item) 255 { 256 return item[1]; 257 } 258 259 function cmSplitItem (prefix, isMain, vertical) 260 { 261 var classStr = 'cm' + prefix; 262 if (isMain) 263 { 264 classStr += 'Main'; 265 if (vertical) 266 classStr += 'HSplit'; 267 else 268 classStr += 'VSplit'; 269 } 270 else 271 classStr += 'HSplit'; 272 return eval (classStr); 273 } 274 275 // 276 // draw the sub menu recursively 277 // 278 function cmDrawSubMenu (subMenu, prefix, id, nodeProperties, zIndexStart, menuInfo, menuID) 279 { 280 var str = '<div class="' + prefix + 'SubMenu" id="' + id + '" style="z-index: ' + zIndexStart + ';position: absolute; top: 0px; left: 0px;">'; 281 if (nodeProperties.subMenuHeader) 282 str += nodeProperties.subMenuHeader; 283 284 str += '<table summary="sub menu" id="' + id + 'Table" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">'; 285 286 var strSub = ''; 287 288 var item; 289 var idSub; 290 var hasChild; 291 292 var i; 293 294 var classStr; 295 296 for (i = 5; i < subMenu.length; ++i) 297 { 298 item = subMenu[i]; 299 if (!item) 300 continue; 301 302 if (item == _cmSplit) 303 item = cmSplitItem (prefix, 0, true); 304 item.parentItem = subMenu; 305 item.subMenuID = id; 306 307 hasChild = (item.length > 5); 308 idSub = hasChild ? cmNewID () : null; 309 310 str += '<tr class="' + prefix + 'MenuItem"'; 311 if (item[0] != _cmNoClick) 312 str += cmActionItem (item, 0, idSub, menuInfo, menuID); 313 else 314 str += cmNoClickItem (item, 0, idSub, menuInfo, menuID); 315 str += '>' 316 317 if (item[0] == _cmNoAction || item[0] == _cmNoClick) 318 { 319 str += cmNoActionItem (item); 320 str += '</tr>'; 321 continue; 322 } 323 324 classStr = prefix + 'Menu'; 325 classStr += hasChild ? 'Folder' : 'Item'; 326 327 str += '<td class="' + classStr + 'Left">'; 328 329 if (item[0] != null) 330 str += item[0]; 331 else 332 str += hasChild ? nodeProperties.folderLeft : nodeProperties.itemLeft; 333 334 str += '</td><td class="' + classStr + 'Text">' + item[1]; 335 336 str += '</td><td class="' + classStr + 'Right">'; 337 338 if (hasChild) 339 { 340 str += nodeProperties.folderRight; 341 strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, zIndexStart + nodeProperties.zIndexInc, menuInfo, menuID); 342 } 343 else 344 str += nodeProperties.itemRight; 345 str += '</td></tr>'; 346 } 347 348 str += '</table>'; 349 350 if (nodeProperties.subMenuFooter) 351 str += nodeProperties.subMenuFooter; 352 str += '</div>' + strSub; 353 return str; 354 } 355 356 // 357 // The function that builds the menu inside the specified element id. 358 // 359 // id id of the element 360 // orient orientation of the menu in [hv][ub][lr] format 361 // menu the menu object to be drawn 362 // nodeProperties properties for the theme 363 // prefix prefix of the theme 364 // 365 function cmDraw (id, menu, orient, nodeProperties, prefix) 366 { 367 var obj = cmGetObject (id); 368 369 if (!prefix) 370 prefix = nodeProperties.prefix; 371 if (!prefix) 372 prefix = ''; 373 if (!nodeProperties) 374 nodeProperties = _cmNodeProperties; 375 if (!orient) 376 orient = 'hbr'; 377 378 var menuID = cmAllocMenu (id, menu, orient, nodeProperties, prefix); 379 var menuInfo = _cmMenuList[menuID]; 380 381 // setup potentially missing properties 382 if (!nodeProperties.delay) 383 nodeProperties.delay = _cmNodeProperties.delay; 384 if (!nodeProperties.clickOpen) 385 nodeProperties.clickOpen = _cmNodeProperties.clickOpen; 386 if (!nodeProperties.zIndexStart) 387 nodeProperties.zIndexStart = _cmNodeProperties.zIndexStart; 388 if (!nodeProperties.zIndexInc) 389 nodeProperties.zIndexInc = _cmNodeProperties.zIndexInc; 390 if (!nodeProperties.offsetHMainAdjust) 391 nodeProperties.offsetHMainAdjust = _cmNodeProperties.offsetHMainAdjust; 392 if (!nodeProperties.offsetVMainAdjust) 393 nodeProperties.offsetVMainAdjust = _cmNodeProperties.offsetVMainAdjust; 394 if (!nodeProperties.offsetSubAdjust) 395 nodeProperties.offsetSubAdjust = _cmNodeProperties.offsetSubAdjust; 396 // save user setting on frame masking 397 menuInfo.cmFrameMasking = _cmFrameMasking; 398 399 var str = '<table summary="main menu" class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '">'; 400 var strSub = ''; 401 402 var vertical; 403 404 // draw the main menu items 405 if (orient.charAt (0) == 'h') 406 { 407 str += '<tr>'; 408 vertical = false; 409 } 410 else 411 { 412 vertical = true; 413 } 414 415 var i; 416 var item; 417 var idSub; 418 var hasChild; 419 420 var classStr; 421 422 for (i = 0; i < menu.length; ++i) 423 { 424 item = menu[i]; 425 426 if (!item) 427 continue; 428 429 item.menu = menu; 430 item.subMenuID = id; 431 432 str += vertical ? '<tr' : '<td'; 433 str += ' class="' + prefix + 'MainItem"'; 434 435 hasChild = (item.length > 5); 436 idSub = hasChild ? cmNewID () : null; 437 438 str += cmActionItem (item, 1, idSub, menuInfo, menuID) + '>'; 439 440 if (item == _cmSplit) 441 item = cmSplitItem (prefix, 1, vertical); 442 443 if (item[0] == _cmNoAction || item[0] == _cmNoClick) 444 { 445 str += cmNoActionItem (item); 446 str += vertical? '</tr>' : '</td>'; 447 continue; 448 } 449 450 classStr = prefix + 'Main' + (hasChild ? 'Folder' : 'Item'); 451 452 str += vertical ? '<td' : '<span'; 453 str += ' class="' + classStr + 'Left">'; 454 455 str += (item[0] == null) ? (hasChild ? nodeProperties.mainFolderLeft : nodeProperties.mainItemLeft) 456 : item[0]; 457 str += vertical ? '</td>' : '</span>'; 458 459 str += vertical ? '<td' : '<span'; 460 str += ' class="' + classStr + 'Text">'; 461 str += item[1]; 462 463 str += vertical ? '</td>' : '</span>'; 464 465 str += vertical ? '<td' : '<span'; 466 str += ' class="' + classStr + 'Right">'; 467 468 str += hasChild ? nodeProperties.mainFolderRight : nodeProperties.mainItemRight; 469 470 str += vertical ? '</td>' : '</span>'; 471 472 str += vertical ? '</tr>' : '</td>'; 473 474 if (hasChild) 475 strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, nodeProperties.zIndexStart, menuInfo, menuID); 476 } 477 if (!vertical) 478 str += '</tr>'; 479 str += '</table>' + strSub; 480 obj.innerHTML = str; 481 } 482 483 // 484 // The function builds the menu inside the specified element id. 485 // 486 // This function is similar to cmDraw except that menu is taken from HTML node 487 // rather a javascript tree. This feature allows links to be scanned by search 488 // bots. 489 // 490 // This function basically converts HTML node to a javascript tree, and then calls 491 // cmDraw to draw the actual menu, replacing the hidden menu tree. 492 // 493 // Format: 494 // <div id="menu"> 495 // <ul style="visibility: hidden"> 496 // <li><span>icon</span><a href="link" title="description">main menu text</a> 497 // <ul> 498 // <li><span>icon</span><a href="link" title="description">submenu item</a> 499 // </li> 500 // </ul> 501 // </li> 502 // </ul> 503 // </div> 504 // 505 function cmDrawFromText (id, orient, nodeProperties, prefix) 506 { 507 var domMenu = cmGetObject (id); 508 var menu = null; 509 for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 510 { 511 if (!currentDomItem.tagName) 512 continue; 513 var tag = currentDomItem.tagName.toLowerCase (); 514 if (tag != 'ul' && tag != 'ol') 515 continue; 516 menu = cmDrawFromTextSubMenu (currentDomItem); 517 break; 518 } 519 if (menu) 520 cmDraw (id, menu, orient, nodeProperties, prefix); 521 } 522 523 // 524 // a recursive function that build menu tree structure 525 // 526 function cmDrawFromTextSubMenu (domMenu) 527 { 528 var items = new Array (); 529 for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 530 { 531 if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'li') 532 continue; 533 if (currentDomItem.firstChild == null) 534 { 535 items[items.length] = _cmSplit; 536 continue; 537 } 538 var item = new Array (); 539 var currentItem = currentDomItem.firstChild; 540 var hasAction = false; 541 for (; currentItem; currentItem = currentItem.nextSibling) 542 { 543 // scan for span or div tag 544 if (!currentItem.tagName) 545 continue; 546 if (currentItem.className == 'cmNoClick') 547 { 548 item[0] = _cmNoClick; 549 item[1] = getActionHTML (currentItem); 550 hasAction = true; 551 break; 552 } 553 if (currentItem.className == 'cmNoAction') 554 { 555 item[0] = _cmNoAction; 556 item[1] = getActionHTML (currentItem); 557 hasAction = true; 558 break; 559 } 560 var tag = currentItem.tagName.toLowerCase (); 561 if (tag != 'span') 562 continue; 563 if (!currentItem.firstChild) 564 item[0] = null; 565 else 566 item[0] = currentItem.innerHTML; 567 currentItem = currentItem.nextSibling; 568 break; 569 } 570 if (hasAction) 571 { 572 items[items.length] = item; 573 continue; 574 } 575 if (!currentItem) 576 continue; 577 for (; currentItem; currentItem = currentItem.nextSibling) 578 { 579 if (!currentItem.tagName) 580 continue; 581 var tag = currentItem.tagName.toLowerCase (); 582 if (tag == 'a') 583 { 584 item[1] = currentItem.innerHTML; 585 item[2] = currentItem.href; 586 item[3] = currentItem.target; 587 item[4] = currentItem.title; 588 if (item[4] == '') 589 item[4] = null; 590 } 591 else if (tag == 'span' || tag == 'div') 592 { 593 item[1] = currentItem.innerHTML; 594 item[2] = null; 595 item[3] = null; 596 item[4] = null; 597 } 598 break; 599 } 600 601 for (; currentItem; currentItem = currentItem.nextSibling) 602 { 603 // scan for span tag 604 if (!currentItem.tagName) 605 continue; 606 var tag = currentItem.tagName.toLowerCase (); 607 if (tag != 'ul' && tag != 'ol') 608 continue; 609 var subMenuItems = cmDrawFromTextSubMenu (currentItem); 610 for (i = 0; i < subMenuItems.length; ++i) 611 item[i + 5] = subMenuItems[i]; 612 break; 613 } 614 items[items.length] = item; 615 } 616 return items; 617 } 618 619 // 620 // obtain the actual action item's action, which is inside a 621 // table. The first row should be it 622 // 623 function getActionHTML (htmlNode) 624 { 625 var returnVal = '<td></td><td></td><td></td>'; 626 var currentDomItem; 627 // find the table first 628 for (currentDomItem = htmlNode.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 629 { 630 if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'table') 631 break; 632 } 633 if (!currentDomItem) 634 return returnVal; 635 // skip over tbody 636 for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 637 { 638 if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tbody') 639 break; 640 } 641 if (!currentDomItem) 642 return returnVal; 643 // get the first tr 644 for (currentDomItem = currentDomItem.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 645 { 646 if (currentDomItem.tagName && currentDomItem.tagName.toLowerCase () == 'tr') 647 break; 648 } 649 if (!currentDomItem) 650 return returnVal; 651 return currentDomItem.innerHTML; 652 } 653 654 // 655 // get the DOM object associated with the item 656 // 657 function cmGetMenuItem (item) 658 { 659 if (!item.subMenuID) 660 return null; 661 var subMenu = cmGetObject (item.subMenuID); 662 // we are dealing with a main menu item 663 if (item.menu) 664 { 665 var menu = item.menu; 666 // skip over table, tbody, tr, reach td 667 subMenu = subMenu.firstChild.firstChild.firstChild.firstChild; 668 var i; 669 for (i = 0; i < menu.length; ++i) 670 { 671 if (menu[i] == item) 672 return subMenu; 673 subMenu = subMenu.nextSibling; 674 } 675 } 676 else if (item.parentItem) // sub menu item 677 { 678 var menu = item.parentItem; 679 var table = cmGetObject (item.subMenuID + 'Table'); 680 if (!table) 681 return null; 682 // skip over table, tbody, reach tr 683 subMenu = table.firstChild.firstChild; 684 var i; 685 for (i = 5; i < menu.length; ++i) 686 { 687 if (menu[i] == item) 688 return subMenu; 689 subMenu = subMenu.nextSibling; 690 } 691 } 692 return null; 693 } 694 695 // 696 // disable a menu item 697 // 698 function cmDisableItem (item, prefix) 699 { 700 if (!item) 701 return; 702 var menuItem = cmGetMenuItem (item); 703 if (!menuItem) 704 return; 705 if (item.menu) 706 menuItem.className = prefix + 'MainItemDisabled'; 707 else 708 menuItem.className = prefix + 'MenuItemDisabled'; 709 item.isDisabled = true; 710 } 711 712 // 713 // enable a menu item 714 // 715 function cmEnableItem (item, prefix) 716 { 717 if (!item) 718 return; 719 var menuItem = cmGetMenuItem (item); 720 if (!menuItem) 721 return; 722 if (item.menu) 723 menu.className = prefix + 'MainItem'; 724 else 725 menu.className = prefix + 'MenuItem'; 726 item.isDisabled = true; 727 } 728 729 ////////////////////////////////////////////////////////////////////// 730 // 731 // Mouse Event Handling Functions 732 // 733 ////////////////////////////////////////////////////////////////////// 734 735 // 736 // action should be taken for mouse moving in to the menu item 737 // 738 // Here we just do things concerning this menu item, w/o opening sub menus. 739 // 740 function cmItemMouseOver (obj, isMain, idSub, menuID, index, calledByOpenSub) 741 { 742 if (!calledByOpenSub && _cmClicked) 743 { 744 cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index); 745 return; 746 } 747 748 clearTimeout (_cmTimeOut); 749 750 if (_cmItemList[index].isDisabled) 751 return; 752 753 var prefix = _cmMenuList[menuID].prefix; 754 755 if (!obj.cmMenuID) 756 { 757 obj.cmMenuID = menuID; 758 obj.cmIsMain = isMain; 759 } 760 761 var thisMenu = cmGetThisMenu (obj, prefix); 762 763 // insert obj into cmItems if cmItems doesn't have obj 764 if (!thisMenu.cmItems) 765 thisMenu.cmItems = new Array (); 766 var i; 767 for (i = 0; i < thisMenu.cmItems.length; ++i) 768 { 769 if (thisMenu.cmItems[i] == obj) 770 break; 771 } 772 if (i == thisMenu.cmItems.length) 773 { 774 //thisMenu.cmItems.push (obj); 775 thisMenu.cmItems[i] = obj; 776 } 777 778 // hide the previous submenu that is not this branch 779 if (_cmCurrentItem) 780 { 781 // occationally, we get this case when user 782 // move the mouse slowly to the border 783 if (_cmCurrentItem == obj || _cmCurrentItem == thisMenu) 784 { 785 var item = _cmItemList[index]; 786 cmSetStatus (item); 787 return; 788 } 789 790 var thatMenuInfo = _cmMenuList[_cmCurrentItem.cmMenuID]; 791 var thatPrefix = thatMenuInfo.prefix; 792 var thatMenu = cmGetThisMenu (_cmCurrentItem, thatPrefix); 793 794 if (thatMenu != thisMenu.cmParentMenu) 795 { 796 if (_cmCurrentItem.cmIsMain) 797 _cmCurrentItem.className = thatPrefix + 'MainItem'; 798 else 799 _cmCurrentItem.className = thatPrefix + 'MenuItem'; 800 if (thatMenu.id != idSub) 801 cmHideMenu (thatMenu, thisMenu, thatMenuInfo); 802 } 803 } 804 805 // okay, set the current menu to this obj 806 _cmCurrentItem = obj; 807 808 // just in case, reset all items in this menu to MenuItem 809 cmResetMenu (thisMenu, prefix); 810 811 var item = _cmItemList[index]; 812 var isDefaultItem = cmIsDefaultItem (item); 813 814 if (isDefaultItem) 815 { 816 if (isMain) 817 obj.className = prefix + 'MainItemHover'; 818 else 819 obj.className = prefix + 'MenuItemHover'; 820 } 821 822 cmSetStatus (item); 823 } 824 825 // 826 // action should be taken for mouse moving in to the menu item 827 // 828 // This function also opens sub menu 829 // 830 function cmItemMouseOverOpenSub (obj, isMain, idSub, menuID, index) 831 { 832 clearTimeout (_cmTimeOut); 833 834 if (_cmItemList[index].isDisabled) 835 return; 836 837 cmItemMouseOver (obj, isMain, idSub, menuID, index, true); 838 839 if (idSub) 840 { 841 var subMenu = cmGetObject (idSub); 842 var menuInfo = _cmMenuList[menuID]; 843 var orient = menuInfo.orient; 844 var prefix = menuInfo.prefix; 845 cmShowSubMenu (obj, isMain, subMenu, menuInfo); 846 } 847 } 848 849 // 850 // action should be taken for mouse moving out of the menu item 851 // 852 function cmItemMouseOut (obj, isMain, idSub, menuID, index) 853 { 854 var delayTime = _cmMenuList[menuID].nodeProperties.delay; 855 _cmTimeOut = window.setTimeout ('cmHideMenuTime ()', delayTime); 856 window.defaultStatus = ''; 857 } 858 859 // 860 // action should be taken for mouse button down at a menu item 861 // 862 function cmItemMouseDown (obj, isMain, idSub, menuID, index) 863 { 864 if (_cmItemList[index].isDisabled) 865 return; 866 867 if (cmIsDefaultItem (_cmItemList[index])) 868 { 869 var prefix = _cmMenuList[menuID].prefix; 870 if (obj.cmIsMain) 871 obj.className = prefix + 'MainItemActive'; 872 else 873 obj.className = prefix + 'MenuItemActive'; 874 } 875 } 876 877 // 878 // action should be taken for mouse button down at a menu item 879 // this is one also opens submenu if needed 880 // 881 function cmItemMouseDownOpenSub (obj, isMain, idSub, menuID, index) 882 { 883 if (_cmItemList[index].isDisabled) 884 return; 885 886 _cmClicked = true; 887 cmItemMouseDown (obj, isMain, idSub, menuID, index); 888 889 if (idSub) 890 { 891 var subMenu = cmGetObject (idSub); 892 var menuInfo = _cmMenuList[menuID]; 893 cmShowSubMenu (obj, isMain, subMenu, menuInfo); 894 } 895 } 896 897 // 898 // action should be taken for mouse button up at a menu item 899 // 900 function cmItemMouseUp (obj, isMain, idSub, menuID, index) 901 { 902 if (_cmItemList[index].isDisabled) 903 return; 904 905 var item = _cmItemList[index]; 906 907 var link = null, target = '_self'; 908 909 if (item.length > 2) 910 link = item[2]; 911 if (item.length > 3 && item[3]) 912 target = item[3]; 913 914 if (link != null) 915 { 916 _cmClicked = false; 917 window.open (link, target); 918 } 919 920 var menuInfo = _cmMenuList[menuID]; 921 var prefix = menuInfo.prefix; 922 var thisMenu = cmGetThisMenu (obj, prefix); 923 924 var hasChild = (item.length > 5); 925 if (!hasChild) 926 { 927 if (cmIsDefaultItem (item)) 928 { 929 if (obj.cmIsMain) 930 obj.className = prefix + 'MainItem'; 931 else 932 obj.className = prefix + 'MenuItem'; 933 } 934 cmHideMenu (thisMenu, null, menuInfo); 935 } 936 else 937 { 938 if (cmIsDefaultItem (item)) 939 { 940 if (obj.cmIsMain) 941 obj.className = prefix + 'MainItemHover'; 942 else 943 obj.className = prefix + 'MenuItemHover'; 944 } 945 } 946 } 947 948 ////////////////////////////////////////////////////////////////////// 949 // 950 // Mouse Event Support Utility Functions 951 // 952 ////////////////////////////////////////////////////////////////////// 953 954 // 955 // move submenu to the appropriate location 956 // 957 function cmMoveSubMenu (obj, isMain, subMenu, menuInfo) 958 { 959 var orient = menuInfo.orient; 960 961 var offsetAdjust; 962 963 if (isMain) 964 { 965 if (orient.charAt (0) == 'h') 966 offsetAdjust = menuInfo.nodeProperties.offsetHMainAdjust; 967 else 968 offsetAdjust = menuInfo.nodeProperties.offsetVMainAdjust; 969 } 970 else 971 offsetAdjust = menuInfo.nodeProperties.offsetSubAdjust; 972 973 if (!isMain && orient.charAt (0) == 'h') 974 orient = 'v' + orient.charAt (1) + orient.charAt (2); 975 976 var mode = String (orient); 977 var p = subMenu.offsetParent; 978 var subMenuWidth = cmGetWidth (subMenu); 979 var horiz = cmGetHorizontalAlign (obj, mode, p, subMenuWidth); 980 if (mode.charAt (0) == 'h') 981 { 982 if (mode.charAt (1) == 'b') 983 subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) + offsetAdjust[1]) + 'px'; 984 else 985 subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu) - offsetAdjust[1]) + 'px'; 986 if (horiz == 'r') 987 subMenu.style.left = (cmGetXAt (obj, p) + offsetAdjust[0]) + 'px'; 988 else 989 subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth - offsetAdjust[0]) + 'px'; 990 } 991 else 992 { 993 if (horiz == 'r') 994 subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) + offsetAdjust[0]) + 'px'; 995 else 996 subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth - offsetAdjust[0]) + 'px'; 997 if (mode.charAt (1) == 'b') 998 subMenu.style.top = (cmGetYAt (obj, p) + offsetAdjust[1]) + 'px'; 999 else 1000 subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu) + offsetAdjust[1]) + 'px'; 1001 } 1002 1003 // IE specific iframe masking method 1004 /*@cc_on 1005 @if (@_jscript_version >= 5.5) 1006 if (menuInfo.cmFrameMasking) 1007 { 1008 if (!subMenu.cmFrameObj) 1009 { 1010 var frameObj = cmAllocFrame (); 1011 subMenu.cmFrameObj = frameObj; 1012 } 1013 1014 var frameObj = subMenu.cmFrameObj; 1015 frameObj.style.zIndex = subMenu.style.zIndex - 1; 1016 frameObj.style.left = (cmGetX (subMenu) - cmGetX (frameObj.offsetParent)) + 'px'; 1017 frameObj.style.top = (cmGetY (subMenu) - cmGetY (frameObj.offsetParent)) + 'px'; 1018 frameObj.style.width = cmGetWidth (subMenu) + 'px'; 1019 frameObj.style.height = cmGetHeight (subMenu) + 'px'; 1020 frameObj.style.display = 'block'; 1021 } 1022 @end 1023 @*/ 1024 if (horiz != orient.charAt (2)) 1025 orient = orient.charAt (0) + orient.charAt (1) + horiz; 1026 return orient; 1027 } 1028 1029 // 1030 // automatically re-adjust the menu position based on available screen size. 1031 // 1032 function cmGetHorizontalAlign (obj, mode, p, subMenuWidth) 1033 { 1034 var horiz = mode.charAt (2); 1035 if (!(document.body)) 1036 return horiz; 1037 var body = document.body; 1038 var browserLeft; 1039 var browserRight; 1040 if (window.innerWidth) 1041 { 1042 // DOM window attributes 1043 browserLeft = window.pageXOffset; 1044 browserRight = window.innerWidth + browserLeft; 1045 } 1046 else if (body.clientWidth) 1047 { 1048 // IE attributes 1049 browserLeft = body.clientLeft; 1050 browserRight = body.clientWidth + browserLeft; 1051 } 1052 else 1053 return horiz; 1054 if (mode.charAt (0) == 'h') 1055 { 1056 if (horiz == 'r' && (cmGetXAt (obj) + subMenuWidth) > browserRight) 1057 horiz = 'l'; 1058 if (horiz == 'l' && (cmGetXAt (obj) + cmGetWidth (obj) - subMenuWidth) < browserLeft) 1059 horiz = 'r'; 1060 return horiz; 1061 } 1062 else 1063 { 1064 if (horiz == 'r' && (cmGetXAt (obj, p) + cmGetWidth (obj) + subMenuWidth) > browserRight) 1065 horiz = 'l'; 1066 if (horiz == 'l' && (cmGetXAt (obj, p) - subMenuWidth) < browserLeft) 1067 horiz = 'r'; 1068 return horiz; 1069 } 1070 } 1071 1072 // 1073 // show the subMenu w/ specified orientation 1074 // also move it to the correct coordinates 1075 // 1076 function cmShowSubMenu (obj, isMain, subMenu, menuInfo) 1077 { 1078 var prefix = menuInfo.prefix; 1079 1080 if (!subMenu.cmParentMenu) 1081 { 1082 // establish the tree w/ back edge 1083 var thisMenu = cmGetThisMenu (obj, prefix); 1084 subMenu.cmParentMenu = thisMenu; 1085 if (!thisMenu.cmSubMenu) 1086 thisMenu.cmSubMenu = new Array (); 1087 thisMenu.cmSubMenu[thisMenu.cmSubMenu.length] = subMenu; 1088 } 1089 1090 var effectInstance = subMenu.cmEffect; 1091 if (effectInstance) 1092 effectInstance.showEffect (true); 1093 else 1094 { 1095 // position the sub menu only if we are not already showing the submenu 1096 var orient = cmMoveSubMenu (obj, isMain, subMenu, menuInfo); 1097 subMenu.cmOrient = orient; 1098 1099 var forceShow = false; 1100 if (subMenu.style.visibility != 'visible' && menuInfo.nodeProperties.effect) 1101 { 1102 try 1103 { 1104 effectInstance = menuInfo.nodeProperties.effect.getInstance (subMenu, orient); 1105 effectInstance.showEffect (false); 1106 } 1107 catch (e) 1108 { 1109 forceShow = true; 1110 subMenu.cmEffect = null; 1111 } 1112 } 1113 else 1114 forceShow = true; 1115 1116 if (forceShow) 1117 { 1118 subMenu.style.visibility = 'visible'; 1119 /*@cc_on 1120 @if (@_jscript_version >= 5.5) 1121 if (subMenu.cmFrameObj) 1122 subMenu.cmFrameObj.style.display = 'block'; 1123 @end 1124 @*/ 1125 } 1126 } 1127 1128 if (!_cmHideObjects) 1129 { 1130 _cmHideObjects = 2; // default = not hide, may change behavior later 1131 try 1132 { 1133 if (window.opera) 1134 { 1135 if (parseInt (navigator.appVersion) < 9) 1136 _cmHideObjects = 1; 1137 } 1138 } 1139 catch (e) 1140 { 1141 } 1142 } 1143 1144 if (_cmHideObjects == 1) 1145 { 1146 if (!subMenu.cmOverlap) 1147 subMenu.cmOverlap = new Array (); 1148 cmHideControl ("IFRAME", subMenu); 1149 cmHideControl ("OBJECT", subMenu); 1150 } 1151 } 1152 1153 // 1154 // reset all the menu items to class MenuItem in thisMenu 1155 // 1156 function cmResetMenu (thisMenu, prefix) 1157 { 1158 if (thisMenu.cmItems) 1159 { 1160 var i; 1161 var str; 1162 var items = thisMenu.cmItems; 1163 for (i = 0; i < items.length; ++i) 1164 { 1165 if (items[i].cmIsMain) 1166 { 1167 if (items[i].className == (prefix + 'MainItemDisabled')) 1168 continue; 1169 } 1170 else 1171 { 1172 if (items[i].className == (prefix + 'MenuItemDisabled')) 1173 continue; 1174 } 1175 if (items[i].cmIsMain) 1176 str = prefix + 'MainItem'; 1177 else 1178 str = prefix + 'MenuItem'; 1179 if (items[i].className != str) 1180 items[i].className = str; 1181 } 1182 } 1183 } 1184 1185 // 1186 // called by the timer to hide the menu 1187 // 1188 function cmHideMenuTime () 1189 { 1190 _cmClicked = false; 1191 if (_cmCurrentItem) 1192 { 1193 var menuInfo = _cmMenuList[_cmCurrentItem.cmMenuID]; 1194 var prefix = menuInfo.prefix; 1195 cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, menuInfo); 1196 _cmCurrentItem = null; 1197 } 1198 } 1199 1200 // 1201 // Only hides this menu 1202 // 1203 function cmHideThisMenu (thisMenu, menuInfo) 1204 { 1205 var effectInstance = thisMenu.cmEffect; 1206 if (effectInstance) 1207 effectInstance.hideEffect (true); 1208 else 1209 { 1210 thisMenu.style.visibility = 'hidden'; 1211 thisMenu.style.top = '0px'; 1212 thisMenu.style.left = '0px'; 1213 thisMenu.cmOrient = null; 1214 /*@cc_on 1215 @if (@_jscript_version >= 5.5) 1216 if (thisMenu.cmFrameObj) 1217 { 1218 var frameObj = thisMenu.cmFrameObj; 1219 frameObj.style.display = 'none'; 1220 frameObj.style.width = '1px'; 1221 frameObj.style.height = '1px'; 1222 thisMenu.cmFrameObj = null; 1223 cmFreeFrame (frameObj); 1224 } 1225 @end 1226 @*/ 1227 } 1228 1229 cmShowControl (thisMenu); 1230 thisMenu.cmItems = null; 1231 } 1232 1233 // 1234 // hide thisMenu, children of thisMenu, as well as the ancestor 1235 // of thisMenu until currentMenu is encountered. currentMenu 1236 // will not be hidden 1237 // 1238 function cmHideMenu (thisMenu, currentMenu, menuInfo) 1239 { 1240 var prefix = menuInfo.prefix; 1241 var str = prefix + 'SubMenu'; 1242 1243 // hide the down stream menus 1244 if (thisMenu.cmSubMenu) 1245 { 1246 var i; 1247 for (i = 0; i < thisMenu.cmSubMenu.length; ++i) 1248 { 1249 cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo); 1250 } 1251 } 1252 1253 // hide the upstream menus 1254 while (thisMenu && thisMenu != currentMenu) 1255 { 1256 cmResetMenu (thisMenu, prefix); 1257 if (thisMenu.className == str) 1258 { 1259 cmHideThisMenu (thisMenu, menuInfo); 1260 } 1261 else 1262 break; 1263 thisMenu = cmGetThisMenu (thisMenu.cmParentMenu, prefix); 1264 } 1265 } 1266 1267 // 1268 // hide thisMenu as well as its sub menus if thisMenu is not 1269 // already hidden 1270 // 1271 function cmHideSubMenu (thisMenu, menuInfo) 1272 { 1273 if (thisMenu.style.visibility == 'hidden') 1274 return; 1275 if (thisMenu.cmSubMenu) 1276 { 1277 var i; 1278 for (i = 0; i < thisMenu.cmSubMenu.length; ++i) 1279 { 1280 cmHideSubMenu (thisMenu.cmSubMenu[i], menuInfo); 1281 } 1282 } 1283 var prefix = menuInfo.prefix; 1284 cmResetMenu (thisMenu, prefix); 1285 cmHideThisMenu (thisMenu, menuInfo); 1286 } 1287 1288 // 1289 // hide a control such as IFRAME 1290 // 1291 function cmHideControl (tagName, subMenu) 1292 { 1293 var x = cmGetX (subMenu); 1294 var y = cmGetY (subMenu); 1295 var w = subMenu.offsetWidth; 1296 var h = subMenu.offsetHeight; 1297 1298 var i; 1299 for (i = 0; i < document.all.tags(tagName).length; ++i) 1300 { 1301 var obj = document.all.tags(tagName)[i]; 1302 if (!obj || !obj.offsetParent) 1303 continue; 1304 1305 // check if the object and the subMenu overlap 1306 1307 var ox = cmGetX (obj); 1308 var oy = cmGetY (obj); 1309 var ow = obj.offsetWidth; 1310 var oh = obj.offsetHeight; 1311 1312 if (ox > (x + w) || (ox + ow) < x) 1313 continue; 1314 if (oy > (y + h) || (oy + oh) < y) 1315 continue; 1316 1317 // if object is already made hidden by a different 1318 // submenu then we dont want to put it on overlap list of 1319 // of a submenu a second time. 1320 // - bug fixed by Felix Zaslavskiy 1321 if(obj.style.visibility == 'hidden') 1322 continue; 1323 1324 //subMenu.cmOverlap.push (obj); 1325 subMenu.cmOverlap[subMenu.cmOverlap.length] = obj; 1326 obj.style.visibility = 'hidden'; 1327 } 1328 } 1329 1330 // 1331 // show the control hidden by the subMenu 1332 // 1333 function cmShowControl (subMenu) 1334 { 1335 if (subMenu.cmOverlap) 1336 { 1337 var i; 1338 for (i = 0; i < subMenu.cmOverlap.length; ++i) 1339 subMenu.cmOverlap[i].style.visibility = ""; 1340 } 1341 subMenu.cmOverlap = null; 1342 } 1343 1344 // 1345 // returns the main menu or the submenu table where this obj (menu item) 1346 // is in 1347 // 1348 function cmGetThisMenu (obj, prefix) 1349 { 1350 var str1 = prefix + 'SubMenu'; 1351 var str2 = prefix + 'Menu'; 1352 while (obj) 1353 { 1354 if (obj.className == str1 || obj.className == str2) 1355 return obj; 1356 obj = obj.parentNode; 1357 } 1358 return null; 1359 } 1360 1361 // 1362 // A special effect function to hook the menu which contains 1363 // special effect object to the timer. 1364 // 1365 function cmTimeEffect (menuID, show, delayTime) 1366 { 1367 window.setTimeout ('cmCallEffect("' + menuID + '",' + show + ')', delayTime); 1368 } 1369 1370 // 1371 // A special effect function. Called by timer. 1372 // 1373 function cmCallEffect (menuID, show) 1374 { 1375 var menu = cmGetObject (menuID); 1376 if (!menu || !menu.cmEffect) 1377 return; 1378 try 1379 { 1380 if (show) 1381 menu.cmEffect.showEffect (false); 1382 else 1383 menu.cmEffect.hideEffect (false); 1384 } 1385 catch (e) 1386 { 1387 } 1388 } 1389 1390 // 1391 // return true if this item is handled using default handlers 1392 // 1393 function cmIsDefaultItem (item) 1394 { 1395 if (item == _cmSplit || item[0] == _cmNoAction || item[0] == _cmNoClick) 1396 return false; 1397 return true; 1398 } 1399 1400 // 1401 // returns the object baring the id 1402 // 1403 function cmGetObject (id) 1404 { 1405 if (document.all) 1406 return document.all[id]; 1407 return document.getElementById (id); 1408 } 1409 1410 // 1411 // functions that obtain the width of an HTML element. 1412 // 1413 function cmGetWidth (obj) 1414 { 1415 var width = obj.offsetWidth; 1416 if (width > 0 || !cmIsTRNode (obj)) 1417 return width; 1418 if (!obj.firstChild) 1419 return 0; 1420 // use TABLE's length can cause an extra pixel gap 1421 //return obj.parentNode.parentNode.offsetWidth; 1422 1423 // use the left and right child instead 1424 return obj.lastChild.offsetLeft - obj.firstChild.offsetLeft + cmGetWidth (obj.lastChild); 1425 } 1426 1427 // 1428 // functions that obtain the height of an HTML element. 1429 // 1430 function cmGetHeight (obj) 1431 { 1432 var height = obj.offsetHeight; 1433 if (height > 0 || !cmIsTRNode (obj)) 1434 return height; 1435 if (!obj.firstChild) 1436 return 0; 1437 // use the first child's height 1438 return obj.firstChild.offsetHeight; 1439 } 1440 1441 // 1442 // functions that obtain the coordinates of an HTML element 1443 // 1444 function cmGetX (obj) 1445 { 1446 if (!obj) 1447 return 0; 1448 var x = 0; 1449 1450 do 1451 { 1452 x += obj.offsetLeft; 1453 obj = obj.offsetParent; 1454 } 1455 while (obj); 1456 return x; 1457 } 1458 1459 function cmGetXAt (obj, elm) 1460 { 1461 var x = 0; 1462 1463 while (obj && obj != elm) 1464 { 1465 x += obj.offsetLeft; 1466 obj = obj.offsetParent; 1467 } 1468 if (obj == elm) 1469 return x; 1470 return x - cmGetX (elm); 1471 } 1472 1473 function cmGetY (obj) 1474 { 1475 if (!obj) 1476 return 0; 1477 var y = 0; 1478 do 1479 { 1480 y += obj.offsetTop; 1481 obj = obj.offsetParent; 1482 } 1483 while (obj); 1484 return y; 1485 } 1486 1487 function cmIsTRNode (obj) 1488 { 1489 var tagName = obj.tagName; 1490 return tagName == "TR" || tagName == "tr" || tagName == "Tr" || tagName == "tR"; 1491 } 1492 1493 // 1494 // get the Y position of the object. In case of TR element though, 1495 // we attempt to adjust the value. 1496 // 1497 function cmGetYAt (obj, elm) 1498 { 1499 var y = 0; 1500 1501 if (!obj.offsetHeight && cmIsTRNode (obj)) 1502 { 1503 var firstTR = obj.parentNode.firstChild; 1504 obj = obj.firstChild; 1505 y -= firstTR.firstChild.offsetTop; 1506 } 1507 1508 while (obj && obj != elm) 1509 { 1510 y += obj.offsetTop; 1511 obj = obj.offsetParent; 1512 } 1513 1514 if (obj == elm) 1515 return y; 1516 return y - cmGetY (elm); 1517 } 1518 1519 // 1520 // extract description from the menu item and set the status text 1521 // 1522 function cmSetStatus (item) 1523 { 1524 var descript = ''; 1525 if (item.length > 4) 1526 descript = (item[4] != null) ? item[4] : (item[2] ? item[2] : descript); 1527 else if (item.length > 2) 1528 descript = (item[2] ? item[2] : descript); 1529 1530 window.defaultStatus = descript; 1531 } 1532 1533 // 1534 // debug function, ignore :) 1535 // 1536 function cmGetProperties (obj) 1537 { 1538 if (obj == undefined) 1539 return 'undefined'; 1540 if (obj == null) 1541 return 'null'; 1542 1543 var msg = obj + ':\n'; 1544 var i; 1545 for (i in obj) 1546 msg += i + ' = ' + obj[i] + '; '; 1547 return msg; 1548 } 1549 1550 /* v2.0.3 1. Fix an issue with IE6 displaying menu over HTTPS connection. 1551 Thanks to Paul Horton for reporting the bug and testing 1552 possible solutions. */ 1553 /* v2.0.2 1. Minor clean up and some attempts to reduce memory leak in IE. */ 1554 /* v2.0.1 1. Disable iframe masking for IE7 since it is no longer necessary. */ 1555 /* v2.0 1. improves the way handling flash/iframe/select boxes in IE 1556 and firefox and Opera 9. Hiding these elements is no 1557 longer necessary. For older versions of Opera, flash/iframe 1558 still need to be hidden. 1559 2. Improves cmDrawFromText (). Also allows custom actions. 1560 3. Improves clickOpen behavior. Now once a submenu is opened, 1561 opening other sub menus no longer requires clicking. 1562 4. Special Effects. This version has hooks that allow people 1563 to install special effects to various themes. 1564 5. For a given menu item, cmGetMenuitem(item) provides the ability 1565 to find the corresponding DOM element. 1566 6. Disable API. If you know which item to disable, you can call 1567 cmDisableItem(item, themePrefix) and cmEnableItem(item, themePrefix). 1568 However, you will have to provide your own CSS for the item. 1569 For purposes other than to disable an item, cmGetMenuItem (item) 1570 is provided for locating HTML DOM element of the menu item in concern. 1571 7. Better z-index. Now you can specify in the theme property the 1572 starting z-index and incremental step for submenus. 1573 8. Allow themes to insert additional elements before and after 1574 the sub menu table. 1575 9. Improved themes. More organized and easier to customize. 1576 10. Add a flag to control hiding/nohiding objects/iframes. By default, 1577 only Opera before 9 hides objects. 1578 11. Add new property options to control submenu positions to fine tune 1579 the look. 1580 12. It is no longer necessary to specify the theme name while calling 1581 cmDraw and cmDrawFromText. Currently it still accepts it, but it 1582 will not in the future. 1583 */ 1584 /* v1.4.4 1. a quick fix for a bug for _cmSplit checking. reported by 1585 Son Nguyen. 1586 */ 1587 /* v1.4.3 1. changed how _cmSplit is handled a bit so that _cmNoClick can work 1588 properly. All splits in predefined themes are changed to use 1589 _cmNoClick instead of _cmNoAction. 1590 */ 1591 /* v1.4.2 1. fixed _cmNoClick mouse hoover bug. 1592 2. fixed a statusbar text problem that cause text to disappear when 1593 hoovering mouse within the same menu item. 1594 3. changed the behavior of cmDrawFromText s.t. if the title of the 1595 of a link is empty, the actual url is used as text. To clear 1596 this link information, title needs to be ' '. 1597 */ 1598 /* v1.4.1 1. fixed a problem introduced in 1.4 where re-entering a main menu 1599 item which doesn't have a child can disable its hover setting. 1600 Apparently I deleted an extra line of code when I was doing 1601 cleaning up. Reported by David Maliachi and a few others. 1602 */ 1603 /* JSCookMenu v1.4 1. fixed a minor td cell closure problem. Thanks to Georg Lorenz 1604 <georg@lonux.de> for discovering that. 1605 2. added clickOpen to nodeProperties. See _cmNodeProperties for 1606 description. Basically menus can be opened on click only. 1607 3. added an ability to draw menu from an html node instead of a javascript 1608 tree, making this script search bot friendly (I hope?). 1609 */ 1610 /* JSCookMenu v1.31 1. fix a bug on IE with causes submenus to display at the top 1611 left corner due to doctype. The fix was provided by 1612 Burton Strauss <Burton@ntopsupport.com>. 1613 */ 1614 /* JSCookMenu v1.3 1. automatically realign (left and right) the submenu when 1615 client space is not enough. 1616 2. add _cmNoClick to get rid of menu closing behavior 1617 on the particular menu item, to make it possible for things 1618 such as search box to be inside the menu. 1619 */ 1620 /* JSCookMenu v1.25 1. fix Safari positioning issue. The problem is that all TR elements are located 1621 at the top left corner. Thus, need to obtain the "virtual" 1622 position of these element could be at. 1623 */ 1624 /* JSCookMenu v1.24 1. fix window based control hiding bug 1625 thanks to Felix Zaslavskiy <felix@bebinary.com> for the fix. 1626 */ 1627 /* JSCookMenu v1.23 1. correct a position bug when the container is positioned. 1628 thanks to Andre <anders@netspace.net.au> for narrowing down 1629 the problem. 1630 */ 1631 /* JSCookMenu v1.22 1. change Array.push (obj) call to Array[length] = obj. 1632 Suggestion from Dick van der Kaaden <dick@netrex.nl> to 1633 make the script compatible with IE 5.0 1634 2. Changed theme files a little to add z-index: 100 for sub 1635 menus. This change is necessary for Netscape to avoid 1636 a display problem. 1637 3. some changes to the DOM structure to make this menu working 1638 on Netscape 6.0 (tested). The main reason is that NN6 does 1639 not do absolute positioning with tables. Therefore an extra 1640 div layer must be put around the table. 1641 */ 1642 /* JSCookMenu v1.21 1. fixed a bug that didn't add 'px' as part of coordinates. 1643 JSCookMenu should be XHTML validator friendly now. 1644 2. removed unnecessary display attribute and corresponding 1645 theme entry to fix a problem that Netscape sometimes 1646 render Office theme incorrectly 1647 */ 1648 /* JSCookMenu v1.2. 1. fix the problem of showing status in Netscape 1649 2. changed the handler parameters a bit to allow 1650 string literals to be passed to javascript based 1651 links 1652 3. having null in target field would cause the link 1653 to be opened in the current window, but this behavior 1654 could change in the future releases 1655 */ 1656 /* JSCookMenu v1.1. added ability to hide controls in IE to show submenus properly */ 1657 /* JSCookMenu v1.01. cmDraw generates XHTML code */ 1658 /* JSCookMenu v1.0. (c) Copyright 2002 by Heng Yuan */
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed May 23 00:05:01 2012 | Cross-referenced by PHPXref 0.7 |
| Mambo API: Mambo is Free software released under the GNU/General Public License, Version 2 |