1// SpryMenuBar.js - version 0.12 - Spry Pre-Release 1.6.1 2// 3// Copyright (c) 2006. Adobe Systems Incorporated. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are met: 8// 9// * Redistributions of source code must retain the above copyright notice, 10// this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above copyright notice, 12// this list of conditions and the following disclaimer in the documentation 13// and/or other materials provided with the distribution. 14// * Neither the name of Adobe Systems Incorporated nor the names of its 15// contributors may be used to endorse or promote products derived from this 16// software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28// POSSIBILITY OF SUCH DAMAGE. 29 30/******************************************************************************* 31 32 SpryMenuBar.js 33 This file handles the JavaScript for Spry Menu Bar. You should have no need 34 to edit this file. Some highlights of the MenuBar object is that timers are 35 used to keep submenus from showing up until the user has hovered over the parent 36 menu item for some time, as well as a timer for when they leave a submenu to keep 37 showing that submenu until the timer fires. 38 39 *******************************************************************************/ 40 41var Spry; if (!Spry) Spry = {}; if (!Spry.Widget) Spry.Widget = {}; 42 43Spry.BrowserSniff = function() 44{ 45 var b = navigator.appName.toString(); 46 var up = navigator.platform.toString(); 47 var ua = navigator.userAgent.toString(); 48 49 this.mozilla = this.ie = this.opera = this.safari = false; 50 var re_opera = /Opera.([0-9\.]*)/i; 51 var re_msie = /MSIE.([0-9\.]*)/i; 52 var re_gecko = /gecko/i; 53 var re_safari = /(applewebkit|safari)\/([\d\.]*)/i; 54 var r = false; 55 56 if ( (r = ua.match(re_opera))) { 57 this.opera = true; 58 this.version = parseFloat(r[1]); 59 } else if ( (r = ua.match(re_msie))) { 60 this.ie = true; 61 this.version = parseFloat(r[1]); 62 } else if ( (r = ua.match(re_safari))) { 63 this.safari = true; 64 this.version = parseFloat(r[2]); 65 } else if (ua.match(re_gecko)) { 66 var re_gecko_version = /rv:\s*([0-9\.]+)/i; 67 r = ua.match(re_gecko_version); 68 this.mozilla = true; 69 this.version = parseFloat(r[1]); 70 } 71 this.windows = this.mac = this.linux = false; 72 73 this.Platform = ua.match(/windows/i) ? "windows" : 74 (ua.match(/linux/i) ? "linux" : 75 (ua.match(/mac/i) ? "mac" : 76 ua.match(/unix/i)? "unix" : "unknown")); 77 this[this.Platform] = true; 78 this.v = this.version; 79 80 if (this.safari && this.mac && this.mozilla) { 81 this.mozilla = false; 82 } 83}; 84 85Spry.is = new Spry.BrowserSniff(); 86 87// Constructor for Menu Bar 88// element should be an ID of an unordered list (<ul> tag) 89// preloadImage1 and preloadImage2 are images for the rollover state of a menu 90Spry.Widget.MenuBar = function(element, opts) 91{ 92 this.init(element, opts); 93}; 94 95Spry.Widget.MenuBar.prototype.init = function(element, opts) 96{ 97 this.element = this.getElement(element); 98 99 // represents the current (sub)menu we are operating on 100 this.currMenu = null; 101 this.showDelay = 250; 102 this.hideDelay = 600; 103 if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (Spry.is.ie && typeof document.uniqueID == 'undefined')) 104 { 105 // bail on older unsupported browsers 106 return; 107 } 108 109 // Fix IE6 CSS images flicker 110 if (Spry.is.ie && Spry.is.version < 7){ 111 try {
112 document.execCommand("BackgroundImageCache", false, true); 113 } catch(err) {} 114 } 115 116 this.upKeyCode = Spry.Widget.MenuBar.KEY_UP; 117 this.downKeyCode = Spry.Widget.MenuBar.KEY_DOWN; 118 this.leftKeyCode = Spry.Widget.MenuBar.KEY_LEFT; 119 this.rightKeyCode = Spry.Widget.MenuBar.KEY_RIGHT; 120 this.escKeyCode = Spry.Widget.MenuBar.KEY_ESC; 121 122 this.hoverClass = 'MenuBarItemHover'; 123 this.subHoverClass = 'MenuBarItemSubmenuHover'; 124 this.subVisibleClass ='MenuBarSubmenuVisible'; 125 this.hasSubClass = 'MenuBarItemSubmenu'; 126 this.activeClass = 'MenuBarActive'; 127 this.isieClass = 'MenuBarItemIE'; 128 this.verticalClass = 'MenuBarVertical'; 129 this.horizontalClass = 'MenuBarHorizontal'; 130 this.enableKeyboardNavigation = true; 131 132 this.hasFocus = false; 133 // load hover images now 134 if(opts) 135 { 136 for(var k in opts) 137 { 138 if (typeof this[k] == 'undefined') 139 { 140 var rollover = new Image; 141 rollover.src = opts[k]; 142 } 143 } 144 Spry.Widget.MenuBar.setOptions(this, opts); 145 } 146 147 // safari doesn't support tabindex 148 if (Spry.is.safari) 149 this.enableKeyboardNavigation = false; 150 151 if(this.element) 152 { 153 this.currMenu = this.element; 154 var items = this.element.getElementsByTagName('li'); 155 for(var i=0; i<items.length; i++) 156 { 157 if (i > 0 && this.enableKeyboardNavigation) 158 items[i].getElementsByTagName('a')[0].tabIndex='-1'; 159 160 this.initialize(items[i], element); 161 if(Spry.is.ie) 162 { 163 this.addClassName(items[i], this.isieClass); 164 items[i].style.position = "static"; 165 } 166 } 167 if (this.enableKeyboardNavigation) 168 { 169 var self = this; 170 this.addEventListener(document, 'keydown', function(e){self.keyDown(e); }, false); 171 } 172 173 if(Spry.is.ie) 174 { 175 if(this.hasClassName(this.element, this.verticalClass)) 176 { 177 this.element.style.position = "relative"; 178 } 179 var linkitems = this.element.getElementsByTagName('a'); 180 for(var i=0; i<linkitems.length; i++) 181 { 182 linkitems[i].style.position = "relative"; 183 } 184 } 185 } 186}; 187Spry.Widget.MenuBar.KEY_ESC = 27; 188Spry.Widget.MenuBar.KEY_UP = 38; 189Spry.Widget.MenuBar.KEY_DOWN = 40; 190Spry.Widget.MenuBar.KEY_LEFT = 37; 191Spry.Widget.MenuBar.KEY_RIGHT = 39; 192 193Spry.Widget.MenuBar.prototype.getElement = function(ele) 194{ 195 if (ele && typeof ele == "string") 196 return document.getElementById(ele); 197 return ele; 198}; 199 200Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className) 201{ 202 if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1) 203 { 204 return false; 205 } 206 return true; 207}; 208 209Spry.Widget.MenuBar.prototype.addClassName = function(ele, className) 210{ 211 if (!ele || !className || this.hasClassName(ele, className)) 212 return; 213 ele.className += (ele.className ? " " : "") + className; 214}; 215 216Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className) 217{ 218 if (!ele || !className || !this.hasClassName(ele, className)) 219 return; 220 ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), ""); 221}; 222 223// addEventListener for Menu Bar 224// attach an event to a tag without creating obtrusive HTML code 225Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture) 226{ 227 try 228 { 229 if (element.addEventListener) 230 { 231 element.addEventListener(eventType, handler, capture); 232 } 233 else if (element.attachEvent) 234 { 235 element.attachEvent('on' + eventType, handler); 236 } 237 } 238 catch (e) {} 239}; 240 241// createIframeLayer for Menu Bar 242// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX 243Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu) 244{ 245 var layer = document.createElement('iframe'); 246 layer.tabIndex = '-1'; 247 layer.src = 'javascript:""'; 248 layer.frameBorder = '0'; 249 layer.scrolling = 'no'; 250 menu.parentNode.appendChild(layer); 251 252 layer.style.left = menu.offsetLeft + 'px'; 253 layer.style.top = menu.offsetTop + 'px'; 254 layer.style.width = menu.offsetWidth + 'px'; 255 layer.style.height = menu.offsetHeight + 'px'; 256}; 257 258// removeIframeLayer for Menu Bar 259// removes an IFRAME underneath a menu to reveal any form controls and ActiveX 260Spry.Widget.MenuBar.prototype.removeIframeLayer = function(menu) 261{ 262 var layers = ((menu == this.element) ? menu : menu.parentNode).getElementsByTagName('iframe'); 263 while(layers.length > 0) 264 { 265 layers[0].parentNode.removeChild(layers[0]); 266 } 267}; 268 269// clearMenus for Menu Bar 270// root is the top level unordered list (<ul> tag) 271Spry.Widget.MenuBar.prototype.clearMenus = function(root) 272{ 273 var menus = root.getElementsByTagName('ul'); 274 for(var i=0; i<menus.length; i++) 275 this.hideSubmenu(menus[i]); 276 277 this.removeClassName(this.element, this.activeClass); 278}; 279 280// bubbledTextEvent for Menu Bar 281// identify bubbled up text events in Safari so we can ignore them 282Spry.Widget.MenuBar.prototype.bubbledTextEvent = function() 283{ 284 return Spry.is.safari && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget)); 285}; 286 287// showSubmenu for Menu Bar 288// set the proper CSS class on this menu to show it 289Spry.Widget.MenuBar.prototype.showSubmenu = function(menu) 290{ 291 if(this.currMenu) 292 { 293 this.clearMenus(this.currMenu); 294 this.currMenu = null; 295 } 296 297 if(menu) 298 { 299 this.addClassName(menu, this.subVisibleClass); 300 if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE') 301 { 302 if(!this.hasClassName(this.element, this.horizontalClass) || menu.parentNode.parentNode != this.element) 303 { 304 menu.style.top = menu.parentNode.offsetTop + 'px'; 305 } 306 } 307 if(Spry.is.ie && Spry.is.version < 7) 308 { 309 this.createIframeLayer(menu); 310 } 311 } 312 this.addClassName(this.element, this.activeClass); 313}; 314 315// hideSubmenu for Menu Bar 316// remove the proper CSS class on this menu to hide it 317Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu) 318{ 319 if(menu) 320 { 321 this.removeClassName(menu, this.subVisibleClass); 322 if(typeof document.all != 'undefined' && !Spry.is.opera && navigator.vendor != 'KDE') 323 { 324 menu.style.top = ''; 325 menu.style.left = ''; 326 } 327 if(Spry.is.ie && Spry.is.version < 7) 328 this.removeIframeLayer(menu); 329 } 330}; 331 332// initialize for Menu Bar 333// create event listeners for the Menu Bar widget so we can properly 334// show and hide submenus 335Spry.Widget.MenuBar.prototype.initialize = function(listitem, element) 336{ 337 var opentime, closetime; 338 var link = listitem.getElementsByTagName('a')[0]; 339 var submenus = listitem.getElementsByTagName('ul'); 340 var menu = (submenus.length > 0 ? submenus[0] : null); 341 342 if(menu) 343 this.addClassName(link, this.hasSubClass); 344 345 if(!Spry.is.ie) 346 { 347 // define a simple function that comes standard in IE to determine 348 // if a node is within another node 349 listitem.contains = function(testNode) 350 { 351 // this refers to the list item 352 if(testNode == null) 353 return false; 354 355 if(testNode == this) 356 return true; 357 else 358 return this.contains(testNode.parentNode); 359 }; 360 } 361 362 // need to save this for scope further down 363 var self = this; 364 this.addEventListener(listitem, 'mouseover', function(e){self.mouseOver(listitem, e);}, false); 365 this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false); 366 367 if (this.enableKeyboardNavigation) 368 { 369 this.addEventListener(link, 'blur', function(e){self.onBlur(listitem);}, false); 370 this.addEventListener(link, 'focus', function(e){self.keyFocus(listitem, e);}, false); 371 } 372}; 373Spry.Widget.MenuBar.prototype.keyFocus = function (listitem, e) 374{ 375 this.lastOpen = listitem.getElementsByTagName('a')[0]; 376 this.addClassName(this.lastOpen, listitem.getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass); 377 this.hasFocus = true; 378}; 379Spry.Widget.MenuBar.prototype.onBlur = function (listitem) 380{ 381 this.clearSelection(listitem); 382}; 383Spry.Widget.MenuBar.prototype.clearSelection = function(el){ 384 //search any intersection with the current open element 385 if (!this.lastOpen) 386 return; 387 388 if (el) 389 { 390 el = el.getElementsByTagName('a')[0]; 391 392 // check children 393 var item = this.lastOpen; 394 while (item != this.element) 395 { 396 var tmp = el; 397 while (tmp != this.element) 398 { 399 if (tmp == item) 400 return; 401 try{ 402 tmp = tmp.parentNode; 403 }catch(err){break;} 404 } 405 item = item.parentNode; 406 } 407 } 408 var item = this.lastOpen; 409 while (item != this.element) 410 { 411 this.hideSubmenu(item.parentNode); 412 var link = item.getElementsByTagName('a')[0]; 413 this.removeClassName(link, this.hoverClass); 414 this.removeClassName(link, this.subHoverClass); 415 item = item.parentNode; 416 } 417 this.lastOpen = false; 418}; 419Spry.Widget.MenuBar.prototype.keyDown = function (e) 420{ 421 if (!this.hasFocus) 422 return; 423 424 if (!this.lastOpen) 425 { 426 this.hasFocus = false; 427 return; 428 } 429 430 var e = e|| event; 431 var listitem = this.lastOpen.parentNode; 432 var link = this.lastOpen; 433 var submenus = listitem.getElementsByTagName('ul'); 434 var menu = (submenus.length > 0 ? submenus[0] : null); 435 var hasSubMenu = (menu) ? true : false; 436
437 var opts = [listitem, menu, null, this.getSibling(listitem, 'previousSibling'), this.getSibling(listitem, 'nextSibling')]; 438 439 if (!opts[3]) 440 opts[2] = (listitem.parentNode.parentNode.nodeName.toLowerCase() == 'li')?listitem.parentNode.parentNode:null; 441 442 var found = 0; 443 switch (e.keyCode){ 444 case this.upKeyCode: 445 found = this.getElementForKey(opts, 'y', 1); 446 break; 447 case this.downKeyCode: 448 found = this.getElementForKey(opts, 'y', -1); 449 break; 450 case this.leftKeyCode: 451 found = this.getElementForKey(opts, 'x', 1); 452 break; 453 case this.rightKeyCode: 454 found = this.getElementForKey(opts, 'x', -1); 455 break; 456 case this.escKeyCode: 457 case 9: 458 this.clearSelection(); 459 this.hasFocus = false; 460 default: return; 461 } 462 switch (found) 463 { 464 case 0: return; 465 case 1: 466 //subopts 467 this.mouseOver(listitem, e); 468 break; 469 case 2: 470 //parent 471 this.mouseOut(opts[2], e); 472 break; 473 case 3: 474 case 4: 475 // left - right 476 this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass); 477 break; 478 } 479 var link = opts[found].getElementsByTagName('a')[0]; 480 if (opts[found].nodeName.toLowerCase() == 'ul') 481 opts[found] = opts[found].getElementsByTagName('li')[0]; 482 483 this.addClassName(link, opts[found].getElementsByTagName('ul').length > 0 ? this.subHoverClass : this.hoverClass); 484 this.lastOpen = link; 485 opts[found].getElementsByTagName('a')[0].focus(); 486 487 //stop further event handling by the browser 488 return Spry.Widget.MenuBar.stopPropagation(e); 489}; 490Spry.Widget.MenuBar.prototype.mouseOver = function (listitem, e) 491{ 492 var link = listitem.getElementsByTagName('a')[0]; 493 var submenus = listitem.getElementsByTagName('ul'); 494 var menu = (submenus.length > 0 ? submenus[0] : null); 495 var hasSubMenu = (menu) ? true : false; 496 if (this.enableKeyboardNavigation) 497 this.clearSelection(listitem); 498 499 if(this.bubbledTextEvent()) 500 { 501 // ignore bubbled text events 502 return; 503 } 504 505 if (listitem.closetime) 506 clearTimeout(listitem.closetime); 507 508 if(this.currMenu == listitem) 509 { 510 this.currMenu = null; 511 } 512 513 // move the focus too 514 if (this.hasFocus) 515 link.focus(); 516 517 // show menu highlighting 518 this.addClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass); 519 this.lastOpen = link; 520 if(menu && !this.hasClassName(menu, this.subHoverClass)) 521 { 522 var self = this; 523 listitem.opentime = window.setTimeout(function(){self.showSubmenu(menu);}, this.showDelay); 524 } 525}; 526Spry.Widget.MenuBar.prototype.mouseOut = function (listitem, e) 527{ 528 var link = listitem.getElementsByTagName('a')[0]; 529 var submenus = listitem.getElementsByTagName('ul'); 530 var menu = (submenus.length > 0 ? submenus[0] : null); 531 var hasSubMenu = (menu) ? true : false; 532 if(this.bubbledTextEvent()) 533 { 534 // ignore bubbled text events 535 return; 536 } 537 538 var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement); 539 if(!listitem.contains(related)) 540 { 541 if (listitem.opentime) 542 clearTimeout(listitem.opentime); 543 this.currMenu = listitem; 544 545 // remove menu highlighting 546 this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass); 547 if(menu) 548 { 549 var self = this; 550 listitem.closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, this.hideDelay); 551 } 552 if (this.hasFocus) 553 link.blur(); 554 } 555}; 556Spry.Widget.MenuBar.prototype.getSibling = function(element, sibling) 557{ 558 var child = element[sibling]; 559 while (child && child.nodeName.toLowerCase() !='li') 560 child = child[sibling]; 561 562 return child; 563}; 564Spry.Widget.MenuBar.prototype.getElementForKey = function(els, prop, dir) 565{ 566 var found = 0; 567 var rect = Spry.Widget.MenuBar.getPosition; 568 var ref = rect(els[found]); 569 570 var hideSubmenu = false; 571 //make the subelement visible to compute the position 572 if (els[1] && !this.hasClassName(els[1], this.MenuBarSubmenuVisible)) 573 { 574 els[1].style.visibility = 'hidden'; 575 this.showSubmenu(els[1]); 576 hideSubmenu = true; 577 } 578 579 var isVert = this.hasClassName(this.element, this.verticalClass); 580 var hasParent = els[0].parentNode.parentNode.nodeName.toLowerCase() == 'li' ? true : false; 581 582 for (var i = 1; i < els.length; i++){
583 //when navigating on the y axis in vertical menus, ignore children and parents 584 if(prop=='y' && isVert && (i==1 || i==2)) 585 { 586 continue; 587 } 588 //when navigationg on the x axis in the FIRST LEVEL of horizontal menus, ignore children and parents 589 if(prop=='x' && !isVert && !hasParent && (i==1 || i==2)) 590 { 591 continue; 592 } 593 594 if (els[i]) 595 { 596 var tmp = rect(els[i]); 597 if ( (dir * tmp[prop]) < (dir * ref[prop])) 598 { 599 ref = tmp; 600 found = i; 601 } 602 } 603 } 604 605 // hide back the submenu 606 if (els[1] && hideSubmenu){ 607 this.hideSubmenu(els[1]); 608 els[1].style.visibility = ''; 609 } 610 611 return found; 612}; 613Spry.Widget.MenuBar.camelize = function(str) 614{ 615 if (str.indexOf('-') == -1){ 616 return str; 617 } 618 var oStringList = str.split('-'); 619 var isFirstEntry = true; 620 var camelizedString = ''; 621 622 for(var i=0; i < oStringList.length; i++) 623 { 624 if(oStringList[i].length>0) 625 { 626 if(isFirstEntry) 627 { 628 camelizedString = oStringList[i]; 629 isFirstEntry = false; 630 } 631 else 632 { 633 var s = oStringList[i]; 634 camelizedString += s.charAt(0).toUpperCase() + s.substring(1); 635 } 636 } 637 } 638 639 return camelizedString; 640}; 641 642Spry.Widget.MenuBar.getStyleProp = function(element, prop) 643{ 644 var value; 645 try 646 { 647 if (element.style) 648 value = element.style[Spry.Widget.MenuBar.camelize(prop)]; 649 650 if (!value) 651 if (document.defaultView && document.defaultView.getComputedStyle) 652 { 653 var css = document.defaultView.getComputedStyle(element, null); 654 value = css ? css.getPropertyValue(prop) : null; 655 } 656 else if (element.currentStyle) 657 { 658 value = element.currentStyle[Spry.Widget.MenuBar.camelize(prop)]; 659 } 660 } 661 catch (e) {} 662 663 return value == 'auto' ? null : value; 664}; 665Spry.Widget.MenuBar.getIntProp = function(element, prop) 666{ 667 var a = parseInt(Spry.Widget.MenuBar.getStyleProp(element, prop),10); 668 if (isNaN(a)) 669 return 0; 670 return a; 671}; 672 673Spry.Widget.MenuBar.getPosition = function(el, doc) 674{ 675 doc = doc || document; 676 if (typeof(el) == 'string') { 677 el = doc.getElementById(el); 678 } 679 680 if (!el) { 681 return false; 682 } 683 684 if (el.parentNode === null || Spry.Widget.MenuBar.getStyleProp(el, 'display') == 'none') { 685 //element must be visible to have a box 686 return false; 687 } 688 689 var ret = {x:0, y:0}; 690 var parent = null; 691 var box; 692 693 if (el.getBoundingClientRect) { // IE 694 box = el.getBoundingClientRect(); 695 var scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop; 696 var scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft; 697 ret.x = box.left + scrollLeft; 698 ret.y = box.top + scrollTop; 699 } else if (doc.getBoxObjectFor) { // gecko 700 box = doc.getBoxObjectFor(el); 701 ret.x = box.x; 702 ret.y = box.y; 703 } else { // safari/opera 704 ret.x = el.offsetLeft; 705 ret.y = el.offsetTop; 706 parent = el.offsetParent; 707 if (parent != el) { 708 while (parent) { 709 ret.x += parent.offsetLeft; 710 ret.y += parent.offsetTop; 711 parent = parent.offsetParent; 712 } 713 } 714 // opera & (safari absolute) incorrectly account for body offsetTop 715 if (Spry.is.opera || Spry.is.safari && Spry.Widget.MenuBar.getStyleProp(el, 'position') == 'absolute') 716 ret.y -= doc.body.offsetTop; 717 } 718 if (el.parentNode) 719 parent = el.parentNode; 720 else 721 parent = null; 722 if (parent.nodeName){ 723 var cas = parent.nodeName.toUpperCase(); 724 while (parent && cas != 'BODY' && cas != 'HTML') { 725 cas = parent.nodeName.toUpperCase(); 726 ret.x -= parent.scrollLeft; 727 ret.y -= parent.scrollTop; 728 if (parent.parentNode) 729 parent = parent.parentNode; 730 else 731 parent = null; 732 } 733 } 734 return ret; 735}; 736 737Spry.Widget.MenuBar.stopPropagation = function(ev) 738{ 739 if (ev.stopPropagation) 740 ev.stopPropagation(); 741 else 742 ev.cancelBubble = true; 743 if (ev.preventDefault) 744 ev.preventDefault(); 745 else 746 ev.returnValue = false; 747}; 748 749Spry.Widget.MenuBar.setOptions = function(obj, optionsObj, ignoreUndefinedProps) 750{ 751 if (!optionsObj) 752 return; 753 for (var optionName in optionsObj) 754 { 755 if (ignoreUndefinedProps && optionsObj[optionName] == undefined) 756 continue; 757 obj[optionName] = optionsObj[optionName]; 758 } 759};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.