1var Spry; 2if(!Spry) 3{ 4 Spry = {}; 5} 6if(!Spry.Widget) 7{ 8 Spry.Widget = {}; 9} 10 11// Constructor for Menu Bar 12// element should be an ID of an unordered list (<ul> tag) 13// preloadImage1 and preloadImage2 are images for the rollover state of a menu 14Spry.Widget.MenuBar = function(element, opts) 15{ 16 this.init(element, opts); 17}; 18 19Spry.Widget.MenuBar.prototype.init = function(element, opts) 20{ 21 this.element = this.getElement(element); 22 23 // represents the current (sub)menu we are operating on 24 this.currMenu = null; 25 26 var isie = (typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE'); 27 if(typeof document.getElementById == 'undefined' || (navigator.vendor == 'Apple Computer, Inc.' && typeof window.XMLHttpRequest == 'undefined') || (isie && typeof document.uniqueID == 'undefined')) 28 { 29 // bail on older unsupported browsers 30 return; 31 } 32 33 // load hover images now 34 if(opts) 35 { 36 for(var k in opts) 37 { 38 var rollover = new Image; 39 rollover.src = opts[k]; 40 } 41 } 42 43 if(this.element) 44 { 45 this.currMenu = this.element; 46 var items = this.element.getElementsByTagName('li'); 47 for(var i=0; i<items.length; i++) 48 { 49 this.initialize(items[i], element, isie); 50 if(isie) 51 { 52 this.addClassName(items[i], "MenuBarItemIE"); 53 items[i].style.position = "static"; 54 } 55 } 56 if(isie) 57 { 58 if(this.hasClassName(this.element, "MenuBarVertical")) 59 { 60 this.element.style.position = "relative"; 61 } 62 var linkitems = this.element.getElementsByTagName('a'); 63 for(var i=0; i<linkitems.length; i++) 64 { 65 linkitems[i].style.position = "relative"; 66 } 67 } 68 } 69}; 70 71Spry.Widget.MenuBar.prototype.getElement = function(ele) 72{ 73 if (ele && typeof ele == "string") 74 return document.getElementById(ele); 75 return ele; 76}; 77 78Spry.Widget.MenuBar.prototype.hasClassName = function(ele, className) 79{ 80 if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1) 81 { 82 return false; 83 } 84 return true; 85}; 86 87Spry.Widget.MenuBar.prototype.addClassName = function(ele, className) 88{ 89 if (!ele || !className || this.hasClassName(ele, className)) 90 return; 91 ele.className += (ele.className ? " " : "") + className; 92}; 93 94Spry.Widget.MenuBar.prototype.removeClassName = function(ele, className) 95{ 96 if (!ele || !className || !this.hasClassName(ele, className)) 97 return; 98 ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), ""); 99}; 100 101// addEventListener for Menu Bar 102// attach an event to a tag without creating obtrusive HTML code 103Spry.Widget.MenuBar.prototype.addEventListener = function(element, eventType, handler, capture) 104{ 105 try 106 { 107 if (element.addEventListener) 108 { 109 element.addEventListener(eventType, handler, capture); 110 } 111 else if (element.attachEvent) 112 { 113 element.attachEvent('on' + eventType, handler); 114 } 115 } 116 catch (e) {} 117}; 118 119// createIframeLayer for Menu Bar 120// creates an IFRAME underneath a menu so that it will show above form controls and ActiveX 121Spry.Widget.MenuBar.prototype.createIframeLayer = function(menu) 122{ 123 var layer = document.createElement('iframe'); 124 layer.tabIndex = '-1'; 125 layer.src = 'javascript:false;'; 126 menu.parentNode.appendChild(layer); 127 128 layer.style.left = menu.offsetLeft + 'px'; 129 layer.style.top = menu.offsetTop + 'px'; 130 layer.style.width = menu.offsetWidth + 'px'; 131 layer.style.height = menu.offsetHeight + 'px'; 132}; 133 134// removeIframeLayer for Menu Bar 135// removes an IFRAME underneath a menu to reveal any form controls and ActiveX 136Spry.Widget.MenuBar.prototype.removeIframeLayer = function(menu) 137{ 138 var layers = menu.parentNode.getElementsByTagName('iframe'); 139 while(layers.length > 0) 140 { 141 layers[0].parentNode.removeChild(layers[0]); 142 } 143}; 144 145// clearMenus for Menu Bar 146// root is the top level unordered list (<ul> tag) 147Spry.Widget.MenuBar.prototype.clearMenus = function(root) 148{ 149 var menus = root.getElementsByTagName('ul'); 150 for(var i=0; i<menus.length; i++) 151 { 152 this.hideSubmenu(menus[i]); 153 } 154 this.removeClassName(this.element, "MenuBarActive"); 155}; 156 157// bubbledTextEvent for Menu Bar 158// identify bubbled up text events in Safari so we can ignore them 159Spry.Widget.MenuBar.prototype.bubbledTextEvent = function() 160{ 161 return (navigator.vendor == 'Apple Computer, Inc.' && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget))); 162}; 163 164// showSubmenu for Menu Bar 165// set the proper CSS class on this menu to show it 166Spry.Widget.MenuBar.prototype.showSubmenu = function(menu) 167{ 168 if(this.currMenu) 169 { 170 this.clearMenus(this.currMenu); 171 this.currMenu = null; 172 } 173 174 if(menu) 175 { 176 this.addClassName(menu, "MenuBarSubmenuVisible"); 177 if(typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE') 178 { 179 if(!this.hasClassName(this.element, "MenuBarHorizontal") || menu.parentNode.parentNode != this.element) 180 { 181 menu.style.top = menu.parentNode.offsetTop + 'px'; 182 } 183 } 184 if(typeof document.uniqueID != "undefined") 185 { 186 this.createIframeLayer(menu); 187 } 188 } 189 this.addClassName(this.element, "MenuBarActive"); 190}; 191 192// hideSubmenu for Menu Bar 193// remove the proper CSS class on this menu to hide it 194Spry.Widget.MenuBar.prototype.hideSubmenu = function(menu) 195{ 196 if(menu) 197 { 198 this.removeClassName(menu, "MenuBarSubmenuVisible"); 199 if(typeof document.all != 'undefined' && typeof window.opera == 'undefined' && navigator.vendor != 'KDE') 200 { 201 menu.style.top = ''; 202 menu.style.left = ''; 203 } 204 this.removeIframeLayer(menu); 205 } 206}; 207 208// initialize for Menu Bar 209// create event listeners for the Menu Bar widget so we can properly 210// show and hide submenus 211Spry.Widget.MenuBar.prototype.initialize = function(listitem, element, isie) 212{ 213 var opentime, closetime; 214 var link = listitem.getElementsByTagName('a')[0]; 215 var submenus = listitem.getElementsByTagName('ul'); 216 var menu = (submenus.length > 0 ? submenus[0] : null); 217 218 var hasSubMenu = false;
219 if(menu) 220 { 221 this.addClassName(link, "MenuBarItemSubmenu"); 222 hasSubMenu = true; 223 } 224 225 if(!isie) 226 { 227 // define a simple function that comes standard in IE to determine 228 // if a node is within another node 229 listitem.contains = function(testNode) 230 { 231 // this refers to the list item 232 if(testNode == null) 233 { 234 return false; 235 } 236 if(testNode == this) 237 { 238 return true; 239 } 240 else 241 { 242 return this.contains(testNode.parentNode); 243 } 244 }; 245 } 246 247 // need to save this for scope further down 248 var self = this; 249 250 this.addEventListener(listitem, 'mouseover', function(e) 251 { 252 if(self.bubbledTextEvent()) 253 { 254 // ignore bubbled text events 255 return; 256 } 257 clearTimeout(closetime); 258 if(self.currMenu == listitem) 259 { 260 self.currMenu = null; 261 } 262 // show menu highlighting 263 self.addClassName(link, hasSubMenu ? "MenuBarItemSubmenuHover" : "MenuBarItemHover"); 264 if(menu && !self.hasClassName(menu, "MenuBarSubmenuVisible")) 265 { 266 opentime = window.setTimeout(function(){self.showSubmenu(menu);}, 250); 267 } 268 }, false); 269 270 this.addEventListener(listitem, 'mouseout', function(e) 271 { 272 if(self.bubbledTextEvent()) 273 { 274 // ignore bubbled text events 275 return; 276 } 277 278 var related = (typeof e.relatedTarget != 'undefined' ? e.relatedTarget : e.toElement); 279 if(!listitem.contains(related)) 280 { 281 clearTimeout(opentime); 282 self.currMenu = listitem; 283 284 // remove menu highlighting 285 self.removeClassName(link, hasSubMenu ? "MenuBarItemSubmenuHover" : "MenuBarItemHover"); 286 if(menu) 287 { 288 closetime = window.setTimeout(function(){self.hideSubmenu(menu);}, 600); 289 } 290 } 291 }, false); 292};
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.