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