[ Index ]
 

Code source de Joomla 1.0.13

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/includes/js/ -> JSCookMenu.js (source)

   1  /*

   2      JSCookMenu v1.4.3.  (c) Copyright 2002-2005 by Heng Yuan

   3  

   4      Permission is hereby granted, free of charge, to any person obtaining a

   5      copy of this software and associated documentation files (the "Software"),

   6      to deal in the Software without restriction, including without limitation

   7      the rights to use, copy, modify, merge, publish, distribute, sublicense,

   8      and/or sell copies of the Software, and to permit persons to whom the

   9      Software is furnished to do so, subject to the following conditions:

  10  

  11      The above copyright notice and this permission notice shall be included

  12      in all copies or substantial portions of the Software.

  13  

  14      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

  15      OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

  16      ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

  17      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

  18      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

  19      FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

  20      DEALINGS IN THE SOFTWARE.

  21  */
  22  
  23  // Globals

  24  var _cmIDCount = 0;
  25  var _cmIDName = 'cmSubMenuID';        // for creating submenu id

  26  
  27  var _cmTimeOut = null;            // how long the menu would stay

  28  var _cmCurrentItem = null;        // the current menu item being selected;

  29  
  30  var _cmNoAction = new Object ();    // indicate that the item cannot be hovered.

  31  var _cmNoClick = new Object ();        // similar to _cmNoAction but does not respond to mouseup/mousedown events

  32  var _cmSplit = new Object ();        // indicate that the item is a menu split

  33  
  34  var _cmItemList = new Array ();        // a simple list of items

  35  
  36  // default node properties

  37  var _cmNodeProperties =
  38  {
  39        // main menu display attributes

  40        //

  41        // Note.  When the menu bar is horizontal,

  42        // mainFolderLeft and mainFolderRight are

  43        // put in <span></span>.  When the menu

  44        // bar is vertical, they would be put in

  45        // a separate TD cell.

  46  
  47        // HTML code to the left of the folder item

  48        mainFolderLeft: '',
  49        // HTML code to the right of the folder item

  50        mainFolderRight: '',
  51      // HTML code to the left of the regular item

  52      mainItemLeft: '',
  53      // HTML code to the right of the regular item

  54      mainItemRight: '',
  55  
  56      // sub menu display attributes

  57  
  58      // HTML code to the left of the folder item

  59      folderLeft: '',
  60      // HTML code to the right of the folder item

  61      folderRight: '',
  62      // HTML code to the left of the regular item

  63      itemLeft: '',
  64      // HTML code to the right of the regular item

  65      itemRight: '',
  66      // cell spacing for main menu

  67      mainSpacing: 0,
  68      // cell spacing for sub menus

  69      subSpacing: 0,
  70      // auto disappear time for submenus in milli-seconds

  71      delay: 500,
  72  
  73      // act on click to open sub menu

  74      // not yet implemented

  75      // 0 : use default behavior

  76      // 1 : hover open in all cases

  77      // 2 : click on main, hover on sub

  78      // 3 : click open in all cases

  79      clickOpen: 1
  80  };
  81  
  82  //////////////////////////////////////////////////////////////////////

  83  //

  84  // Drawing Functions and Utility Functions

  85  //

  86  //////////////////////////////////////////////////////////////////////

  87  
  88  //

  89  // produce a new unique id

  90  //

  91  function cmNewID ()
  92  {
  93      return _cmIDName + (++_cmIDCount);
  94  }
  95  
  96  //

  97  // return the property string for the menu item

  98  //

  99  function cmActionItem (item, prefix, isMain, idSub, orient, nodeProperties)
 100  {
 101      var clickOpen = _cmNodeProperties.clickOpen;
 102      if (nodeProperties.clickOpen)
 103          clickOpen = nodeProperties.clickOpen;
 104  
 105      // var index = _cmItemList.push (item) - 1;

 106      _cmItemList[_cmItemList.length] = item;
 107      var index = _cmItemList.length - 1;
 108      idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');
 109      orient = '\'' + orient + '\'';
 110      prefix = '\'' + prefix + '\'';
 111      var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain);
 112      var returnStr;
 113      if (onClick)
 114          returnStr = ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmousedown="cmItemMouseDownOpenSub (this,' + index + ',' + prefix + ',' + orient + ',' + idSub + ')"';
 115      else
 116          returnStr = ' onmouseover="cmItemMouseOverOpenSub (this,' + prefix + ',' + isMain + ',' + idSub + ',' + orient + ',' + index + ')" onmousedown="cmItemMouseDown (this,' + index + ')"';
 117      return returnStr + ' onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')" onmouseup="cmItemMouseUp (this,' + index + ')"';
 118  }
 119  
 120  //

 121  // this one is used by _cmNoClick to only take care of onmouseover and onmouseout

 122  // events which are associated with menu but not actions associated with menu clicking/closing

 123  //

 124  function cmNoClickItem (item, prefix, isMain, idSub, orient, nodeProperties)
 125  {
 126      // var index = _cmItemList.push (item) - 1;

 127      _cmItemList[_cmItemList.length] = item;
 128      var index = _cmItemList.length - 1;
 129      idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');
 130      orient = '\'' + orient + '\'';
 131      prefix = '\'' + prefix + '\'';
 132      return ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')"';
 133  }
 134  
 135  function cmNoActionItem (item, prefix)
 136  {
 137      return item[1];
 138  }
 139  
 140  function cmSplitItem (prefix, isMain, vertical)
 141  {
 142      var classStr = 'cm' + prefix;
 143      if (isMain)
 144      {
 145          classStr += 'Main';
 146          if (vertical)
 147              classStr += 'HSplit';
 148          else
 149              classStr += 'VSplit';
 150      }
 151      else
 152          classStr += 'HSplit';
 153      return eval (classStr);
 154  }
 155  
 156  //

 157  // draw the sub menu recursively

 158  //

 159  function cmDrawSubMenu (subMenu, prefix, id, orient, nodeProperties)
 160  {
 161      var str = '<div class="' + prefix + 'SubMenu" id="' + id + '"><table summary="sub menu" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">';
 162      var strSub = '';
 163  
 164      var item;
 165      var idSub;
 166      var hasChild;
 167  
 168      var i;
 169  
 170      var classStr;
 171  
 172      for (i = 5; i < subMenu.length; ++i)
 173      {
 174          item = subMenu[i];
 175          if (!item)
 176              continue;
 177  
 178          hasChild = (item.length > 5);
 179          idSub = hasChild ? cmNewID () : null;
 180  
 181          if (item == _cmSplit)
 182              item = cmSplitItem (prefix, 0, true);
 183  
 184          str += '<tr class="' + prefix + 'MenuItem"';
 185          if (item[0] != _cmNoClick)
 186              str += cmActionItem (item, prefix, 0, idSub, orient, nodeProperties);
 187          else
 188              str += cmNoClickItem (item, prefix, 0, idSub, orient, nodeProperties);
 189          str += '>'
 190  
 191          if (item[0] == _cmNoAction || item[0] == _cmNoClick)
 192          {
 193              str += cmNoActionItem (item, prefix);
 194              str += '</tr>';
 195              continue;
 196          }
 197  
 198          classStr = prefix + 'Menu';
 199          classStr += hasChild ? 'Folder' : 'Item';
 200  
 201          str += '<td class="' + classStr + 'Left">';
 202  
 203          if (item[0] != null)
 204              str += item[0];
 205          else
 206              str += hasChild ? nodeProperties.folderLeft : nodeProperties.itemLeft;
 207  
 208          str += '</td><td class="' + classStr + 'Text">' + item[1];
 209  
 210          str += '</td><td class="' + classStr + 'Right">';
 211  
 212          if (hasChild)
 213          {
 214              str += nodeProperties.folderRight;
 215              strSub += cmDrawSubMenu (item, prefix, idSub, orient, nodeProperties);
 216          }
 217          else
 218              str += nodeProperties.itemRight;
 219          str += '</td></tr>';
 220      }
 221  
 222      str += '</table></div>' + strSub;
 223      return str;
 224  }
 225  
 226  //

 227  // The function that builds the menu inside the specified element id.

 228  //

 229  // @param    id    id of the element

 230  //        orient    orientation of the menu in [hv][ab][lr] format

 231  //        menu    the menu object to be drawn

 232  //        nodeProperties    properties for each menu node

 233  //

 234  function cmDraw (id, menu, orient, nodeProperties, prefix)
 235  {
 236      var obj = cmGetObject (id);
 237  
 238      if (!nodeProperties)
 239          nodeProperties = _cmNodeProperties;
 240      if (!prefix)
 241          prefix = '';
 242  
 243      var str = '<table summary="main menu" class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '">';
 244      var strSub = '';
 245  
 246      if (!orient)
 247          orient = 'hbr';
 248  
 249      var orientStr = String (orient);
 250      var orientSub;
 251      var vertical;
 252  
 253      // draw the main menu items

 254      if (orientStr.charAt (0) == 'h')
 255      {
 256          // horizontal menu

 257          orientSub = 'v' + orientStr.substr (1, 2);
 258          str += '<tr>';
 259          vertical = false;
 260      }
 261      else
 262      {
 263          // vertical menu

 264          orientSub = 'v' + orientStr.substr (1, 2);
 265          vertical = true;
 266      }
 267  
 268      var i;
 269      var item;
 270      var idSub;
 271      var hasChild;
 272  
 273      var classStr;
 274  
 275      for (i = 0; i < menu.length; ++i)
 276      {
 277          item = menu[i];
 278  
 279          if (!item)
 280              continue;
 281  
 282          str += vertical ? '<tr' : '<td';
 283          str += ' class="' + prefix + 'MainItem"';
 284  
 285          hasChild = (item.length > 5);
 286          idSub = hasChild ? cmNewID () : null;
 287  
 288          str += cmActionItem (item, prefix, 1, idSub, orient, nodeProperties) + '>';
 289  
 290          if (item == _cmSplit)
 291              item = cmSplitItem (prefix, 1, vertical);
 292  
 293          if (item[0] == _cmNoAction || item[0] == _cmNoClick)
 294          {
 295              str += cmNoActionItem (item, prefix);
 296              str += vertical? '</tr>' : '</td>';
 297              continue;
 298          }
 299  
 300          classStr = prefix + 'Main' + (hasChild ? 'Folder' : 'Item');
 301  
 302          str += vertical ? '<td' : '<span';
 303          str += ' class="' + classStr + 'Left">';
 304  
 305          str += (item[0] == null) ? (hasChild ? nodeProperties.mainFolderLeft : nodeProperties.mainItemLeft)
 306                       : item[0];
 307          str += vertical ? '</td>' : '</span>';
 308  
 309          str += vertical ? '<td' : '<span';
 310          str += ' class="' + classStr + 'Text">';
 311          str += item[1];
 312  
 313          str += vertical ? '</td>' : '</span>';
 314  
 315          str += vertical ? '<td' : '<span';
 316          str += ' class="' + classStr + 'Right">';
 317  
 318          str += hasChild ? nodeProperties.mainFolderRight : nodeProperties.mainItemRight;
 319  
 320          str += vertical ? '</td>' : '</span>';
 321  
 322          str += vertical ? '</tr>' : '</td>';
 323  
 324          if (hasChild)
 325              strSub += cmDrawSubMenu (item, prefix, idSub, orientSub, nodeProperties);
 326      }
 327      if (!vertical)
 328          str += '</tr>';
 329      str += '</table>' + strSub;
 330      obj.innerHTML = str;
 331      //document.write ("<xmp>" + str + "</xmp>");

 332  }
 333  
 334  //

 335  // The function builds the menu inside the specified element id.

 336  //

 337  // This function is similar to cmDraw except that menu is taken from HTML node

 338  // rather a javascript tree.  This feature allows links to be scanned by search

 339  // bots.

 340  //

 341  // This function basically converts HTML node to a javascript tree, and then calls

 342  // cmDraw to draw the actual menu, replacing the hidden menu tree.

 343  //

 344  // Format:

 345  //    <div id="menu">

 346  //        <ul style="visibility: hidden">

 347  //            <li><span>icon</span><a href="link" title="description">main menu text</a>

 348  //                <ul>

 349  //                    <li><span>icon</span><a href="link" title="description">submenu item</a>

 350  //                    </li>

 351  //                </ul>

 352  //            </li>

 353  //        </ul>

 354  //    </div>

 355  //

 356  function cmDrawFromText (id, orient, nodeProperties, prefix)
 357  {
 358      var domMenu = cmGetObject (id);
 359      var menu = null;
 360      for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)
 361      {
 362          if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'ul')
 363              continue;
 364          menu = cmDrawFromTextSubMenu (currentDomItem);
 365          break;
 366      }
 367      if (menu)
 368          cmDraw (id, menu, orient, nodeProperties, prefix);
 369  }
 370  
 371  //

 372  // a recursive function that build menu tree structure

 373  //

 374  function cmDrawFromTextSubMenu (domMenu)
 375  {
 376      var items = new Array ();
 377      for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)
 378      {
 379          if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'li')
 380              continue;
 381          if (currentDomItem.firstChild == null)
 382          {
 383              items[items.length] = _cmSplit;
 384              continue;
 385          }
 386          var item = new Array ();
 387          var currentItem = currentDomItem.firstChild;
 388          for (; currentItem; currentItem = currentItem.nextSibling)
 389          {
 390              // scan for span tag

 391              if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'span')
 392                  continue;
 393              if (!currentItem.firstChild)
 394                  item[0] = null;
 395              else
 396                  item[0] = currentItem.innerHTML;
 397              break;
 398          }
 399          if (!currentItem)
 400              continue;
 401          for (; currentItem; currentItem = currentItem.nextSibling)
 402          {
 403              // scan for span tag

 404              if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'a')
 405                  continue;
 406              item[1] = currentItem.innerHTML;
 407              item[2] = currentItem.href;
 408              item[3] = currentItem.target;
 409              item[4] = currentItem.title;
 410              if (item[4] == '')
 411                  item[4] = null;
 412              break;
 413          }
 414  
 415          for (; currentItem; currentItem = currentItem.nextSibling)
 416          {
 417              // scan for span tag

 418              if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'ul')
 419                  continue;
 420              var subMenuItems = cmDrawFromTextSubMenu (currentItem);
 421              for (i = 0; i < subMenuItems.length; ++i)
 422                  item[i + 5] = subMenuItems[i];
 423              break;
 424          }
 425          items[items.length] = item;
 426      }
 427      return items;
 428  }
 429  
 430  //////////////////////////////////////////////////////////////////////

 431  //

 432  // Mouse Event Handling Functions

 433  //

 434  //////////////////////////////////////////////////////////////////////

 435  
 436  //

 437  // action should be taken for mouse moving in to the menu item

 438  //

 439  // Here we just do things concerning this menu item, w/o opening sub menus.

 440  //

 441  function cmItemMouseOver (obj, prefix, isMain, idSub, index)
 442  {
 443      clearTimeout (_cmTimeOut);
 444  
 445      if (!obj.cmPrefix)
 446      {
 447          obj.cmPrefix = prefix;
 448          obj.cmIsMain = isMain;
 449      }
 450  
 451      var thisMenu = cmGetThisMenu (obj, prefix);
 452  
 453      // insert obj into cmItems if cmItems doesn't have obj

 454      if (!thisMenu.cmItems)
 455          thisMenu.cmItems = new Array ();
 456      var i;
 457      for (i = 0; i < thisMenu.cmItems.length; ++i)
 458      {
 459          if (thisMenu.cmItems[i] == obj)
 460              break;
 461      }
 462      if (i == thisMenu.cmItems.length)
 463      {
 464          //thisMenu.cmItems.push (obj);

 465          thisMenu.cmItems[i] = obj;
 466      }
 467  
 468      // hide the previous submenu that is not this branch

 469      if (_cmCurrentItem)
 470      {
 471          // occationally, we get this case when user

 472          // move the mouse slowly to the border

 473          if (_cmCurrentItem == obj || _cmCurrentItem == thisMenu)
 474          {
 475              var item = _cmItemList[index];
 476              cmSetStatus (item);
 477              return;
 478          }
 479  
 480          var thatPrefix = _cmCurrentItem.cmPrefix;
 481          var thatMenu = cmGetThisMenu (_cmCurrentItem, thatPrefix);
 482  
 483          if (thatMenu != thisMenu.cmParentMenu)
 484          {
 485              if (_cmCurrentItem.cmIsMain)
 486                  _cmCurrentItem.className = thatPrefix + 'MainItem';
 487              else
 488                  _cmCurrentItem.className = thatPrefix + 'MenuItem';
 489              if (thatMenu.id != idSub)
 490                  cmHideMenu (thatMenu, thisMenu, thatPrefix);
 491          }
 492      }
 493  
 494      // okay, set the current menu to this obj

 495      _cmCurrentItem = obj;
 496  
 497      // just in case, reset all items in this menu to MenuItem

 498      cmResetMenu (thisMenu, prefix);
 499  
 500      var item = _cmItemList[index];
 501      var isDefaultItem = cmIsDefaultItem (item);
 502  
 503      if (isDefaultItem)
 504      {
 505          if (isMain)
 506              obj.className = prefix + 'MainItemHover';
 507          else
 508              obj.className = prefix + 'MenuItemHover';
 509      }
 510  
 511      cmSetStatus (item);
 512  }
 513  
 514  //

 515  // action should be taken for mouse moving in to the menu item

 516  //

 517  // This function also opens sub menu

 518  //

 519  function cmItemMouseOverOpenSub (obj, prefix, isMain, idSub, orient, index)
 520  {
 521      cmItemMouseOver (obj, prefix, isMain, idSub, index);
 522  
 523      if (idSub)
 524      {
 525          var subMenu = cmGetObject (idSub);
 526          cmShowSubMenu (obj, prefix, subMenu, orient);
 527      }
 528  }
 529  
 530  //

 531  // action should be taken for mouse moving out of the menu item

 532  //

 533  function cmItemMouseOut (obj, delayTime)
 534  {
 535      if (!delayTime)
 536          delayTime = _cmNodeProperties.delay;
 537      _cmTimeOut = window.setTimeout ('cmHideMenuTime ()', delayTime);
 538      window.defaultStatus = '';
 539  }
 540  
 541  //

 542  // action should be taken for mouse button down at a menu item

 543  //

 544  function cmItemMouseDown (obj, index)
 545  {
 546      if (cmIsDefaultItem (_cmItemList[index]))
 547      {
 548          if (obj.cmIsMain)
 549              obj.className = obj.cmPrefix + 'MainItemActive';
 550          else
 551              obj.className = obj.cmPrefix + 'MenuItemActive';
 552      }
 553  }
 554  
 555  //

 556  // action should be taken for mouse button down at a menu item

 557  // this is one also opens submenu if needed

 558  //

 559  function cmItemMouseDownOpenSub (obj, index, prefix, orient, idSub)
 560  {
 561      cmItemMouseDown (obj, index);
 562  
 563      if (idSub)
 564      {
 565          var subMenu = cmGetObject (idSub);
 566          cmShowSubMenu (obj, prefix, subMenu, orient);
 567      }
 568  }
 569  
 570  //

 571  // action should be taken for mouse button up at a menu item

 572  //

 573  function cmItemMouseUp (obj, index)
 574  {
 575      var item = _cmItemList[index];
 576  
 577      var link = null, target = '_self';
 578  
 579      if (item.length > 2)
 580          link = item[2];
 581      if (item.length > 3 && item[3])
 582          target = item[3];
 583  
 584      if (link != null)
 585      {
 586          window.open (link, target);
 587      }
 588  
 589      var prefix = obj.cmPrefix;
 590      var thisMenu = cmGetThisMenu (obj, prefix);
 591  
 592      var hasChild = (item.length > 5);
 593      if (!hasChild)
 594      {
 595          if (cmIsDefaultItem (item))
 596          {
 597              if (obj.cmIsMain)
 598                  obj.className = prefix + 'MainItem';
 599              else
 600                  obj.className = prefix + 'MenuItem';
 601          }
 602          cmHideMenu (thisMenu, null, prefix);
 603      }
 604      else
 605      {
 606          if (cmIsDefaultItem (item))
 607          {
 608              if (obj.cmIsMain)
 609                  obj.className = prefix + 'MainItemHover';
 610              else
 611                  obj.className = prefix + 'MenuItemHover';
 612          }
 613      }
 614  }
 615  
 616  //////////////////////////////////////////////////////////////////////

 617  //

 618  // Mouse Event Support Utility Functions

 619  //

 620  //////////////////////////////////////////////////////////////////////

 621  
 622  //

 623  // move submenu to the appropriate location

 624  //

 625  // @param    obj    the menu item that opens up the subMenu

 626  //        subMenu    the sub menu to be shown

 627  //        orient    the orientation of the subMenu

 628  //

 629  function cmMoveSubMenu (obj, subMenu, orient)
 630  {
 631      var mode = String (orient);
 632      var p = subMenu.offsetParent;
 633      var subMenuWidth = cmGetWidth (subMenu);
 634      var horiz = cmGetHorizontalAlign (obj, mode, p, subMenuWidth);
 635      if (mode.charAt (0) == 'h')
 636      {
 637          if (mode.charAt (1) == 'b')
 638              subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj)) + 'px';
 639          else
 640              subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu)) + 'px';
 641          if (horiz == 'r')
 642              subMenu.style.left = (cmGetXAt (obj, p)) + 'px';
 643          else
 644              subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth) + 'px';
 645      }
 646      else
 647      {
 648          if (horiz == 'r')
 649              subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj)) + 'px';
 650          else
 651              subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth) + 'px';
 652          if (mode.charAt (1) == 'b')
 653              subMenu.style.top = (cmGetYAt (obj, p)) + 'px';
 654          else
 655              subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu)) + 'px';
 656      }
 657  }
 658  
 659  //

 660  // automatically re-adjust the menu position based on available screen size.

 661  //

 662  function cmGetHorizontalAlign (obj, mode, p, subMenuWidth)
 663  {
 664      var horiz = mode.charAt (2);
 665      if (!(document.body))
 666          return horiz;
 667      var body = document.body;
 668      var browserLeft;
 669      var browserRight;
 670      if (window.innerWidth)
 671      {
 672          // DOM window attributes

 673          browserLeft = window.pageXOffset;
 674          browserRight = window.innerWidth + browserLeft;
 675      }
 676      else if (body.clientWidth)
 677      {
 678          // IE attributes

 679          browserLeft = body.clientLeft;
 680          browserRight = body.clientWidth + browserLeft;
 681      }
 682      else
 683          return horiz;
 684      if (mode.charAt (0) == 'h')
 685      {
 686          if (horiz == 'r' && (cmGetXAt (obj) + subMenuWidth) > browserRight)
 687              horiz = 'l';
 688          if (horiz == 'l' && (cmGetXAt (obj) + cmGetWidth (obj) - subMenuWidth) < browserLeft)
 689              horiz = 'r';
 690          return horiz;
 691      }
 692      else
 693      {
 694          if (horiz == 'r' && (cmGetXAt (obj, p) + cmGetWidth (obj) + subMenuWidth) > browserRight)
 695              horiz = 'l';
 696          if (horiz == 'l' && (cmGetXAt (obj, p) - subMenuWidth) < browserLeft)
 697              horiz = 'r';
 698          return horiz;
 699      }
 700  }
 701  
 702  //

 703  // show the subMenu w/ specified orientation

 704  // also move it to the correct coordinates

 705  //

 706  // @param    obj    the menu item that opens up the subMenu

 707  //        subMenu    the sub menu to be shown

 708  //        orient    the orientation of the subMenu

 709  //

 710  function cmShowSubMenu (obj, prefix, subMenu, orient)
 711  {
 712      if (!subMenu.cmParentMenu)
 713      {
 714          // establish the tree w/ back edge

 715          var thisMenu = cmGetThisMenu (obj, prefix);
 716          subMenu.cmParentMenu = thisMenu;
 717          if (!thisMenu.cmSubMenu)
 718              thisMenu.cmSubMenu = new Array ();
 719          //thisMenu.cmSubMenu.push (subMenu);

 720          thisMenu.cmSubMenu[thisMenu.cmSubMenu.length] = subMenu;
 721      }
 722  
 723      // position the sub menu

 724      cmMoveSubMenu (obj, subMenu, orient);
 725      subMenu.style.visibility = 'visible';
 726  
 727      //

 728      // On IE, controls such as SELECT, OBJECT, IFRAME (before 5.5)

 729      // are window based controls.  So, if the sub menu and these

 730      // controls overlap, sub menu would be hidden behind them.  Thus

 731      // one needs to turn the visibility of these controls off when the

 732      // sub menu is showing, and turn their visibility back on

 733      // when the sub menu is hiding.

 734      //

 735      if (document.all)    // it is IE
 736      {
 737          /* part of Felix Zaslavskiy's fix on hiding controls

 738             not really sure if this part is necessary, but shouldn't

 739             hurt. */
 740          if (!subMenu.cmOverlap)
 741              subMenu.cmOverlap = new Array ();
 742  /*@cc_on @*/

 743  /*@if (@_jscript_version >= 5.5)

 744  @else @*/
 745          cmHideControl ("IFRAME", subMenu);
 746  /*@end @*/

 747          cmHideControl ("SELECT", subMenu);
 748          cmHideControl ("OBJECT", subMenu);
 749      }
 750  }
 751  
 752  //

 753  // reset all the menu items to class MenuItem in thisMenu

 754  //

 755  function cmResetMenu (thisMenu, prefix)
 756  {
 757      if (thisMenu.cmItems)
 758      {
 759          var i;
 760          var str;
 761          var items = thisMenu.cmItems;
 762          for (i = 0; i < items.length; ++i)
 763          {
 764              if (items[i].cmIsMain)
 765                  str = prefix + 'MainItem';
 766              else
 767                  str = prefix + 'MenuItem';
 768              if (items[i].className != str)
 769                  items[i].className = str;
 770          }
 771      }
 772  }
 773  
 774  //

 775  // called by the timer to hide the menu

 776  //

 777  function cmHideMenuTime ()
 778  {
 779      if (_cmCurrentItem)
 780      {
 781          var prefix = _cmCurrentItem.cmPrefix;
 782          cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, prefix);
 783          _cmCurrentItem = null;
 784      }
 785  }
 786  
 787  //

 788  // hide thisMenu, children of thisMenu, as well as the ancestor

 789  // of thisMenu until currentMenu is encountered.  currentMenu

 790  // will not be hidden

 791  //

 792  function cmHideMenu (thisMenu, currentMenu, prefix)
 793  {
 794      var str = prefix + 'SubMenu';
 795  
 796      // hide the down stream menus

 797      if (thisMenu.cmSubMenu)
 798      {
 799          var i;
 800          for (i = 0; i < thisMenu.cmSubMenu.length; ++i)
 801          {
 802              cmHideSubMenu (thisMenu.cmSubMenu[i], prefix);
 803          }
 804      }
 805  
 806      // hide the upstream menus

 807      while (thisMenu && thisMenu != currentMenu)
 808      {
 809          cmResetMenu (thisMenu, prefix);
 810          if (thisMenu.className == str)
 811          {
 812              thisMenu.style.visibility = 'hidden';
 813              cmShowControl (thisMenu);
 814          }
 815          else
 816              break;
 817          thisMenu = cmGetThisMenu (thisMenu.cmParentMenu, prefix);
 818      }
 819  }
 820  
 821  //

 822  // hide thisMenu as well as its sub menus if thisMenu is not

 823  // already hidden

 824  //

 825  function cmHideSubMenu (thisMenu, prefix)
 826  {
 827      if (thisMenu.style.visibility == 'hidden')
 828          return;
 829      if (thisMenu.cmSubMenu)
 830      {
 831          var i;
 832          for (i = 0; i < thisMenu.cmSubMenu.length; ++i)
 833          {
 834              cmHideSubMenu (thisMenu.cmSubMenu[i], prefix);
 835          }
 836      }
 837      cmResetMenu (thisMenu, prefix);
 838      thisMenu.style.visibility = 'hidden';
 839      cmShowControl (thisMenu);
 840  }
 841  
 842  //

 843  // hide a control such as IFRAME

 844  //

 845  function cmHideControl (tagName, subMenu)
 846  {
 847      var x = cmGetX (subMenu);
 848      var y = cmGetY (subMenu);
 849      var w = subMenu.offsetWidth;
 850      var h = subMenu.offsetHeight;
 851  
 852      var i;
 853      for (i = 0; i < document.all.tags(tagName).length; ++i)
 854      {
 855          var obj = document.all.tags(tagName)[i];
 856          if (!obj || !obj.offsetParent)
 857              continue;
 858  
 859          // check if the object and the subMenu overlap

 860  
 861          var ox = cmGetX (obj);
 862          var oy = cmGetY (obj);
 863          var ow = obj.offsetWidth;
 864          var oh = obj.offsetHeight;
 865  
 866          if (ox > (x + w) || (ox + ow) < x)
 867              continue;
 868          if (oy > (y + h) || (oy + oh) < y)
 869              continue;
 870  
 871          // if object is already made hidden by a different

 872          // submenu then we dont want to put it on overlap list of

 873          // of a submenu a second time.

 874          // - bug fixed by Felix Zaslavskiy

 875          if(obj.style.visibility == "hidden")
 876              continue;
 877  
 878          //subMenu.cmOverlap.push (obj);

 879          subMenu.cmOverlap[subMenu.cmOverlap.length] = obj;
 880          obj.style.visibility = "hidden";
 881      }
 882  }
 883  
 884  //

 885  // show the control hidden by the subMenu

 886  //

 887  function cmShowControl (subMenu)
 888  {
 889      if (subMenu.cmOverlap)
 890      {
 891          var i;
 892          for (i = 0; i < subMenu.cmOverlap.length; ++i)
 893              subMenu.cmOverlap[i].style.visibility = "";
 894      }
 895      subMenu.cmOverlap = null;
 896  }
 897  
 898  //

 899  // returns the main menu or the submenu table where this obj (menu item)

 900  // is in

 901  //

 902  function cmGetThisMenu (obj, prefix)
 903  {
 904      var str1 = prefix + 'SubMenu';
 905      var str2 = prefix + 'Menu';
 906      while (obj)
 907      {
 908          if (obj.className == str1 || obj.className == str2)
 909              return obj;
 910          obj = obj.parentNode;
 911      }
 912      return null;
 913  }
 914  
 915  //

 916  // return true if this item is handled using default handlers

 917  //

 918  function cmIsDefaultItem (item)
 919  {
 920      if (item == _cmSplit || item[0] == _cmNoAction || item[0] == _cmNoClick)
 921          return false;
 922      return true;
 923  }
 924  
 925  //

 926  // returns the object baring the id

 927  //

 928  function cmGetObject (id)
 929  {
 930      if (document.all)
 931          return document.all[id];
 932      return document.getElementById (id);
 933  }
 934  
 935  //

 936  // functions that obtain the width of an HTML element.

 937  //

 938  function cmGetWidth (obj)
 939  {
 940      var width = obj.offsetWidth;
 941      if (width > 0 || !cmIsTRNode (obj))
 942          return width;
 943      if (!obj.firstChild)
 944          return 0;
 945      // use TABLE's length can cause an extra pixel gap

 946      //return obj.parentNode.parentNode.offsetWidth;

 947  
 948      // use the left and right child instead

 949      return obj.lastChild.offsetLeft - obj.firstChild.offsetLeft + cmGetWidth (obj.lastChild);
 950  }
 951  
 952  //

 953  // functions that obtain the height of an HTML element.

 954  //

 955  function cmGetHeight (obj)
 956  {
 957      var height = obj.offsetHeight;
 958      if (height > 0 || !cmIsTRNode (obj))
 959          return height;
 960      if (!obj.firstChild)
 961          return 0;
 962      // use the first child's height

 963      return obj.firstChild.offsetHeight;
 964  }
 965  
 966  //

 967  // functions that obtain the coordinates of an HTML element

 968  //

 969  function cmGetX (obj)
 970  {
 971      var x = 0;
 972  
 973      do
 974      {
 975          x += obj.offsetLeft;
 976          obj = obj.offsetParent;
 977      }
 978      while (obj);
 979      return x;
 980  }
 981  
 982  function cmGetXAt (obj, elm)
 983  {
 984      var x = 0;
 985  
 986      while (obj && obj != elm)
 987      {
 988          x += obj.offsetLeft;
 989          obj = obj.offsetParent;
 990      }
 991      if (obj == elm)
 992          return x;
 993      return x - cmGetX (elm);
 994  }
 995  
 996  function cmGetY (obj)
 997  {
 998      var y = 0;
 999      do
1000      {
1001          y += obj.offsetTop;
1002          obj = obj.offsetParent;
1003      }
1004      while (obj);
1005      return y;
1006  }
1007  
1008  function cmIsTRNode (obj)
1009  {
1010      var tagName = obj.tagName;
1011      return tagName == "TR" || tagName == "tr" || tagName == "Tr" || tagName == "tR";
1012  }
1013  
1014  //

1015  // get the Y position of the object.  In case of TR element though,

1016  // we attempt to adjust the value.

1017  //

1018  function cmGetYAt (obj, elm)
1019  {
1020      var y = 0;
1021  
1022      if (!obj.offsetHeight && cmIsTRNode (obj))
1023      {
1024          var firstTR = obj.parentNode.firstChild;
1025          obj = obj.firstChild;
1026          y -= firstTR.firstChild.offsetTop;
1027      }
1028  
1029      while (obj && obj != elm)
1030      {
1031          y += obj.offsetTop;
1032          obj = obj.offsetParent;
1033      }
1034  
1035      if (obj == elm)
1036          return y;
1037      return y - cmGetY (elm);
1038  }
1039  
1040  //

1041  // extract description from the menu item and set the status text

1042  // @param    item    the menu item

1043  //

1044  function cmSetStatus (item)
1045  {
1046      var descript = '';
1047      if (item.length > 4)
1048          descript = (item[4] != null) ? item[4] : (item[2] ? item[2] : descript);
1049      else if (item.length > 2)
1050          descript = (item[2] ? item[2] : descript);
1051  
1052      window.defaultStatus = descript;
1053  }
1054  
1055  //

1056  // debug function, ignore :)

1057  //

1058  function cmGetProperties (obj)
1059  {
1060      if (obj == undefined)
1061          return 'undefined';
1062      if (obj == null)
1063          return 'null';
1064  
1065      var msg = obj + ':\n';
1066      var i;
1067      for (i in obj)
1068          msg += i + ' = ' + obj[i] + '; ';
1069      return msg;
1070  }
1071  
1072  /* v1.4.3            1. changed how _cmSplit is handled a bit so that _cmNoClick can work

1073                          properly.  All splits in predefined themes are changed to use

1074                          _cmNoClick instead of _cmNoAction.

1075  */
1076  /* v1.4.2            1. fixed _cmNoClick mouse hoover bug.

1077                      2. fixed a statusbar text problem that cause text to disappear when

1078                          hoovering mouse within the same menu item.

1079                      3. changed the behavior of cmDrawFromText s.t. if the title of the

1080                          of a link is empty, the actual url is used as text.  To clear

1081                          this link information, title needs to be ' '.

1082  */
1083  /* v1.4.1            1. fixed a problem introduced in 1.4 where re-entering a main menu

1084                          item which doesn't have a child can disable its hover setting.

1085                          Apparently I deleted an extra line of code when I was doing

1086                          cleaning up.  Reported by David Maliachi and a few others.

1087  */
1088  /* JSCookMenu v1.4    1. fixed a minor td cell closure problem.  Thanks to Georg Lorenz

1089                         <georg@lonux.de> for discovering that.

1090                      2. added clickOpen to nodeProperties.  See _cmNodeProperties for

1091                          description.  Basically menus can be opened on click only.

1092                      3. added an ability to draw menu from an html node instead of a javascript

1093                          tree, making this script search bot friendly (I hope?).

1094  */
1095  /* JSCookMenu v1.31 1. fix a bug on IE with causes submenus to display at the top

1096                         left corner due to doctype.  The fix was provided by

1097                         Burton Strauss <Burton@ntopsupport.com>.

1098  */
1099  /* JSCookMenu v1.3    1. automatically realign (left and right) the submenu when

1100                         client space is not enough.

1101                      2. add _cmNoClick to get rid of menu closing behavior

1102                         on the particular menu item, to make it possible for things

1103                         such as search box to be inside the menu.

1104  */
1105  /* JSCookMenu v1.25    1. fix Safari positioning issue.  The problem is that all TR elements are located

1106                         at the top left corner.  Thus, need to obtain the "virtual"

1107                         position of these element could be at.

1108  */
1109  /* JSCookMenu v1.24    1. fix window based control hiding bug

1110                         thanks to Felix Zaslavskiy <felix@bebinary.com> for the fix.

1111  */
1112  /* JSCookMenu v1.23    1. correct a position bug when the container is positioned.

1113                        thanks to Andre <anders@netspace.net.au> for narrowing down

1114                        the problem.

1115  */
1116  /* JSCookMenu v1.22    1. change Array.push (obj) call to Array[length] = obj.

1117                         Suggestion from Dick van der Kaaden <dick@netrex.nl> to

1118                         make the script compatible with IE 5.0

1119                      2. Changed theme files a little to add z-index: 100 for sub

1120                         menus.  This change is necessary for Netscape to avoid

1121                         a display problem.

1122                      3. some changes to the DOM structure to make this menu working

1123                         on Netscape 6.0 (tested).  The main reason is that NN6 does

1124                         not do absolute positioning with tables.  Therefore an extra

1125                         div layer must be put around the table.

1126  */
1127  /* JSCookMenu v1.21    1. fixed a bug that didn't add 'px' as part of coordinates.

1128                         JSCookMenu should be XHTML validator friendly now.

1129                      2. removed unnecessary display attribute and corresponding

1130                         theme entry to fix a problem that Netscape sometimes

1131                         render Office theme incorrectly

1132  */
1133  /* JSCookMenu v1.2.    1. fix the problem of showing status in Netscape

1134                      2. changed the handler parameters a bit to allow

1135                         string literals to be passed to javascript based

1136                         links

1137                      3. having null in target field would cause the link

1138                         to be opened in the current window, but this behavior

1139                         could change in the future releases

1140  */
1141  /* JSCookMenu v1.1.        added ability to hide controls in IE to show submenus properly */

1142  /* JSCookMenu v1.01.    cmDraw generates XHTML code */

1143  /* JSCookMenu v1.0.        (c) Copyright 2002 by Heng Yuan */



Généré le : Wed Nov 21 14:43:32 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics