PageSourceSearch

https://pomologie.com/SpryAssets/SpryMenuBar.js

js pomologie.com collected 2026-10-01 12:23:24 UTC 7,525 bytes, 292 lines download raw bytes

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.